MST

星途 面试题库

面试题:C++ 拷贝构造函数内存管理的复杂场景

假设有一个自定义类 `MyClass`,它包含一个指向动态分配数组的指针成员变量。现在有一个函数 `void func(MyClass obj)`,在函数调用过程中,拷贝构造函数会被调用。请详细描述这个过程中涉及的内存管理操作,并且说明如何实现深拷贝以保证 `func` 函数内部对 `obj` 的操作不会影响原对象。
29.2万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 拷贝构造函数调用过程中的内存管理操作
    • func(MyClass obj) 被调用时,会创建 obj 的副本,这会调用 MyClass 的拷贝构造函数。
    • 在默认的拷贝构造函数(如果未自定义)中,对于指针成员变量,会进行浅拷贝。这意味着新对象的指针会指向与原对象指针相同的动态分配数组的内存地址。这种情况下,如果 func 函数内部对 obj 的指针成员所指向的数组进行修改、释放内存等操作,就会影响原对象,因为它们共享同一块内存。
  2. 实现深拷贝以避免影响原对象
    • MyClass 类中,需要自定义拷贝构造函数来实现深拷贝。
    • 假设 MyClass 类的定义如下:
class MyClass {
private:
    int* data;
    int size;
public:
    MyClass(int s) : size(s) {
        data = new int[size];
    }
    // 自定义拷贝构造函数实现深拷贝
    MyClass(const MyClass& other) : size(other.size) {
        data = new int[size];
        for (int i = 0; i < size; ++i) {
            data[i] = other.data[i];
        }
    }
    ~MyClass() {
        delete[] data;
    }
};
  • 在上述自定义拷贝构造函数中:
    • 首先为新对象的 data 指针分配与原对象 data 所指向数组相同大小的内存。
    • 然后通过循环将原对象数组中的每个元素复制到新分配的内存中。这样,新对象和原对象就有了各自独立的动态分配数组,func 函数内部对 obj 的操作就不会影响原对象。
  • 同时,为了保证内存管理的完整性,还需要定义析构函数来释放动态分配的内存(如上述代码中的 ~MyClass())。如果类中还包含赋值运算符重载函数,也需要在其中实现深拷贝逻辑,以确保在赋值操作时同样不会出现内存共享导致的问题。