MST

星途 面试题库

面试题:C++ 中重写拷贝构造函数时易忽略的浅拷贝问题

请编写一个包含动态分配内存成员变量的C++类,并给出其默认拷贝构造函数和重写后的拷贝构造函数。说明默认拷贝构造函数可能会导致的问题,以及重写的拷贝构造函数如何解决这些问题。
11.4万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
#include <iostream>
#include <cstring>

class MyClass {
private:
    char* data;
    int size;

public:
    // 构造函数
    MyClass(int s) : size(s) {
        data = new char[size];
        std::memset(data, 0, size);
    }

    // 默认拷贝构造函数(会导致浅拷贝问题)
    MyClass(const MyClass& other) : size(other.size), data(other.data) {}

    // 重写的拷贝构造函数(深拷贝)
    MyClass(const MyClass& other) : size(other.size) {
        data = new char[size];
        std::memcpy(data, other.data, size);
    }

    // 析构函数
    ~MyClass() {
        delete[] data;
    }
};

默认拷贝构造函数可能导致的问题:

  1. 浅拷贝问题:默认拷贝构造函数只是简单地复制指针,而不是复制指针指向的内容。这意味着多个对象会共享同一块内存。当其中一个对象销毁时,这块内存被释放,其他对象的指针就会变成野指针,导致程序崩溃。
  2. 内存泄漏:如果多个对象共享同一块内存,当这些对象都试图释放这块内存时(例如在析构函数中),会导致多次释放同一块内存,引发未定义行为。

重写的拷贝构造函数如何解决这些问题:

  1. 深拷贝:重写的拷贝构造函数为新对象分配独立的内存,并将源对象的数据复制到新分配的内存中。这样每个对象都有自己独立的内存空间,不会相互影响。
  2. 避免内存泄漏:由于每个对象都有自己独立的内存,析构函数释放内存时不会出现多次释放同一块内存的情况,从而避免了内存泄漏。