MST

星途 面试题库

面试题:C++ 中自定义类型含有指针成员时重写拷贝构造函数的要点

当一个 C++ 自定义类型包含指针成员变量时,重写拷贝构造函数需要注意哪些关键要点?请结合内存管理和对象生命周期进行阐述,并给出相应的代码示例。
24.4万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 关键要点

    • 深拷贝:由于指针成员变量指向动态分配的内存,拷贝构造函数必须进行深拷贝,即分配新的内存,并将源对象指针所指向的内容复制到新分配的内存中。否则,会导致多个对象共享同一块内存,当其中一个对象销毁时,其他对象的指针就会成为野指针,引发未定义行为。
    • 内存管理:在分配新内存时,要检查是否成功分配,防止内存分配失败。同时,新对象创建后,在其生命周期结束时,需要正确释放动态分配的内存,避免内存泄漏。
    • 对象生命周期:拷贝构造函数创建的新对象应具有独立的生命周期,与源对象互不影响。当源对象或新对象被销毁时,不会影响另一个对象的状态。
  2. 代码示例

#include <iostream>
#include <cstring>

class MyString {
private:
    char* str;
    int length;

public:
    // 构造函数
    MyString(const char* s = nullptr) {
        if (s == nullptr) {
            length = 0;
            str = new char[1];
            str[0] = '\0';
        } else {
            length = std::strlen(s);
            str = new char[length + 1];
            std::strcpy(str, s);
        }
    }

    // 拷贝构造函数
    MyString(const MyString& other) {
        length = other.length;
        str = new char[length + 1];
        std::strcpy(str, other.str);
    }

    // 析构函数
    ~MyString() {
        delete[] str;
    }

    // 重载赋值运算符
    MyString& operator=(const MyString& other) {
        if (this == &other) {
            return *this;
        }
        delete[] str;
        length = other.length;
        str = new char[length + 1];
        std::strcpy(str, other.str);
        return *this;
    }

    void print() const {
        std::cout << str << std::endl;
    }
};

int main() {
    MyString s1("Hello");
    MyString s2(s1);
    s1.print();
    s2.print();
    return 0;
}

在上述代码中,MyString 类包含一个 char* 类型的指针成员变量 str。拷贝构造函数 MyString(const MyString& other) 为新对象分配了独立的内存,并将源对象 other 的字符串内容复制到新分配的内存中,实现了深拷贝。同时,析构函数 ~MyString() 负责释放动态分配的内存,确保对象生命周期结束时不会出现内存泄漏。