下面是关于移动构造函数和移动赋值运算符的示例:
移动构造函数的例子
#include <iostream>
#include <vector>
class MyClass {
public:
std::vector<int> data;
// 默认构造函数
MyClass() {
std::cout << "Default constructor" << std::endl;
}
// 移动构造函数
MyClass(MyClass&& other) noexcept : data(std::move(other.data)) {
std::cout << "Move constructor" << std::endl;
}
// 复制构造函数
MyClass(const MyClass& other) : data(other.data) {
std::cout << "Copy constructor" << std::endl;
}
};
int main() {
MyClass obj1;
obj1.data.push_back(10);
MyClass obj2 = std::move(obj1); // 调用移动构造函数
return 0;
}
说明:
- 当使用
std::move(obj1)
初始化obj2
时,调用了MyClass
的移动构造函数。 - 移动构造函数接收一个右值引用参数,并将资源从
other
移动到新对象。
移动赋值运算符的例子
#include <iostream>
#include <vector>
class MyClass {
public:
std::vector<int> data;
// 默认构造函数
MyClass() {
std::cout << "Default constructor" << std::endl;
}
// 移动赋值运算符
MyClass& operator=(MyClass&& other) noexcept {
std::cout << "Move assignment operator" << std::endl;
if (this != &other) {
data = std::move(other.data);
}
return *this;
}
// 复制赋值运算符
MyClass& operator=(const MyClass& other) {
std::cout << "Copy assignment operator" << std::endl;
if (this != &other) {
data = other.data;
}
return *this;
}
};
int main() {
MyClass obj1;
obj1.data.push_back(20);
MyClass obj2;
obj2 = std::move(obj1); // 调用移动赋值运算符
return 0;
}
说明:
- 使用
std::move(obj1)
将obj1
转换为右值引用,然后赋值给obj2
,调用移动赋值运算符。 - 移动赋值运算符需要检查自赋值,并将资源从
other
移动到当前对象。
注意事项
noexcept
:建议在移动构造函数和移动赋值运算符后添加noexcept
,以便标准库可以进行优化。- 自赋值检查:在移动赋值运算符中,检查
this != &other
,防止自赋值导致未定义行为。 - 资源管理:确保在移动操作后,源对象的资源状态是有效的,但可以是空的。