面试题答案
一键面试移动赋值运算符的作用
移动赋值运算符的主要作用是将一个对象的资源(例如动态分配的内存)“窃取”并移动到另一个对象中,而不是像拷贝赋值那样复制资源。这在对象拥有较大或昂贵资源(如动态分配的大数组)时,可以显著提高效率,避免不必要的资源复制。
与拷贝赋值运算符的主要区别
- 资源处理方式:
- 拷贝赋值运算符:会复制源对象的资源到目标对象,这样源对象和目标对象都拥有独立的资源副本。
- 移动赋值运算符:源对象的资源被转移到目标对象,源对象通常会被置于一个可析构的有效但“空”的状态(例如指针置为
nullptr
),避免了资源的复制。
- 性能:
- 拷贝赋值运算符:由于需要复制资源,开销较大,特别是对于大的资源。
- 移动赋值运算符:主要操作是指针的重新指向等简单操作,开销较小。
简单类移动赋值运算符实现代码
#include <iostream>
#include <memory>
class MyClass {
private:
int* data;
size_t size;
public:
// 构造函数
MyClass(size_t s) : size(s) {
data = new int[s];
std::cout << "Constructor: Allocated memory for MyClass." << std::endl;
}
// 析构函数
~MyClass() {
delete[] data;
std::cout << "Destructor: Released memory of MyClass." << std::endl;
}
// 拷贝赋值运算符
MyClass& operator=(const MyClass& other) {
if (this != &other) {
delete[] data;
size = other.size;
data = new int[size];
for (size_t i = 0; i < size; ++i) {
data[i] = other.data[i];
}
std::cout << "Copy assignment operator: Copied data." << std::endl;
}
return *this;
}
// 移动赋值运算符
MyClass& operator=(MyClass&& other) noexcept {
if (this != &other) {
delete[] data;
data = other.data;
size = other.size;
other.data = nullptr;
other.size = 0;
std::cout << "Move assignment operator: Moved data." << std::endl;
}
return *this;
}
};