面试题答案
一键面试需要手动实现 C++ 移动构造函数的情况
- 资源管理类:当类持有动态分配的资源(如堆内存、文件句柄、网络连接等)时,如果默认的移动构造函数无法正确处理这些资源的转移,就需要手动实现。例如,一个自定义的字符串类
MyString
,内部使用new
分配了字符数组。如果使用默认移动构造函数,可能只是浅拷贝指针,而没有真正转移资源所有权,导致内存管理问题。 - 避免不必要的深拷贝:在某些场景下,对象拷贝代价很高,但对象移动代价相对较低。比如一个包含大数据量的矩阵类
Matrix
,如果默认的拷贝构造函数会复制整个矩阵数据,而移动构造函数可以直接转移矩阵数据的所有权,从而显著提高性能。
实现思路
- 参数:移动构造函数的参数是一个右值引用,例如
ClassName(ClassName&& other)
。这里的&&
表示右值引用,用于绑定临时对象。 - 资源转移:在函数体中,将
other
对象持有的资源直接转移到当前对象。以MyString
类为例:
class MyString {
private:
char* data;
size_t length;
public:
MyString(const char* str) {
length = strlen(str);
data = new char[length + 1];
strcpy(data, str);
}
MyString(MyString&& other) noexcept {
data = other.data;
length = other.length;
other.data = nullptr;
other.length = 0;
}
// 其他成员函数...
~MyString() {
delete[] data;
}
};
在上述代码中,MyString(MyString&& other)
移动构造函数将 other
的 data
指针和 length
转移到当前对象,并将 other
的 data
设为 nullptr
,长度设为 0
。这样就实现了资源的高效转移,而不是复制。同时,为了确保移动操作不会抛出异常,通常将移动构造函数声明为 noexcept
。