MST

星途 面试题库

面试题:C++ 中移动构造函数的实现场景

请举例说明在哪些情况下需要手动实现 C++ 的移动构造函数,并简要阐述其实现思路。
32.9万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

需要手动实现 C++ 移动构造函数的情况

  1. 资源管理类:当类持有动态分配的资源(如堆内存、文件句柄、网络连接等)时,如果默认的移动构造函数无法正确处理这些资源的转移,就需要手动实现。例如,一个自定义的字符串类 MyString,内部使用 new 分配了字符数组。如果使用默认移动构造函数,可能只是浅拷贝指针,而没有真正转移资源所有权,导致内存管理问题。
  2. 避免不必要的深拷贝:在某些场景下,对象拷贝代价很高,但对象移动代价相对较低。比如一个包含大数据量的矩阵类 Matrix,如果默认的拷贝构造函数会复制整个矩阵数据,而移动构造函数可以直接转移矩阵数据的所有权,从而显著提高性能。

实现思路

  1. 参数:移动构造函数的参数是一个右值引用,例如 ClassName(ClassName&& other)。这里的 && 表示右值引用,用于绑定临时对象。
  2. 资源转移:在函数体中,将 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) 移动构造函数将 otherdata 指针和 length 转移到当前对象,并将 otherdata 设为 nullptr,长度设为 0。这样就实现了资源的高效转移,而不是复制。同时,为了确保移动操作不会抛出异常,通常将移动构造函数声明为 noexcept