C++中使用拷贝构造函数实现深拷贝的问题求助
问题根源
你写的拷贝构造逻辑是对的,但**N2 = N1调用的是默认赋值运算符,它做的是浅拷贝**——直接把N1的指针a、b的地址复制给N2,导致两个对象的指针指向同一块堆内存,修改N1的内容自然会影响N2。
拷贝构造函数只在新建对象并初始化时生效(比如Number N2(N1);或Number N2 = N1;),而你代码里的N2已经通过默认构造函数创建完成,此时用=触发的是赋值运算符,不是拷贝构造。
解决方法:重载赋值运算符
给Number类加上重载的赋值运算符,实现深拷贝逻辑,同时处理自赋值和内存泄漏问题:
#include <iostream> using namespace std; class Number { private: int* a; int* b; public: // 默认构造函数 Number() { a = new int; b = new int; *a = 0; *b = 0; } // 带参构造函数 Number(int val1, int val2) { a = new int; b = new int; *a = val1; *b = val2; } // 拷贝构造函数(你原来的实现没问题) Number(const Number& other) { a = new int; b = new int; *a = *(other.a); *b = *(other.b); } // 重载赋值运算符(核心新增部分) Number& operator=(const Number& other) { // 处理自赋值:避免自己赋值给自己时的内存错误 if (this == &other) { return *this; } // 先释放当前对象已有的堆内存,防止泄漏 delete a; delete b; // 重新分配内存并复制值,实现深拷贝 a = new int; b = new int; *a = *(other.a); *b = *(other.b); return *this; // 返回自身,支持链式赋值(比如N3 = N2 = N1) } // 析构函数!必须添加,否则会导致堆内存泄漏 ~Number() { delete a; delete b; } // getters and setters int getA() { return *a; } int getB() { return *b; } void setA(int val) { *a = val; } void setB(int val) { *b = val; } void print() { cout << "value of a: " << *a << " value of b: " << *b << endl; } }; int main() { Number N1(2,3), N2; N1.print(); // 输出:value of a: 2 value of b: 3 N2.print(); // 输出:value of a: 0 value of b: 0 N2 = N1; N1.print(); // 输出:value of a: 2 value of b: 3 N2.print(); // 输出:value of a: 2 value of b: 3 N1.setA(12); N1.print(); // 输出:value of a: 12 value of b: 3 N2.print(); // 输出:value of a: 2 value of b: 3 (现在N2和N1完全独立) }
额外提醒
- 必须加析构函数:你原来的代码没有析构函数,对象销毁时不会释放
a、b指向的堆内存,会造成内存泄漏。 - 自赋值检查不能少:如果跳过这一步,当执行
N1 = N1时,会先释放自己的内存,再去访问已释放的内存,触发未定义行为。 - 若使用C++11及以上版本,还可以实现移动构造和移动赋值来优化性能,但当前先解决深拷贝的核心需求即可。
内容的提问来源于stack exchange,提问作者Abdellah
相关产品推荐
相关产品推荐

