如何为包含其他类对象的类编写拷贝构造函数(深拷贝)
解决B类深拷贝的简洁实现方法
嘿,这个问题我可太熟了!你现在要做的就是给B类实现深拷贝,确保两个B实例各自持有独立的A对象,还不想手动去复制A的每一个成员对吧?其实完全不用那么麻烦,你可以借助A类已经实现的拷贝构造函数来简化操作,甚至用现代C++的智能指针彻底解放手动内存管理。
方法一:利用A的拷贝构造函数实现深拷贝
你已经给A类写好了拷贝构造函数,这就省了大事!在B的拷贝构造和赋值运算符里,直接通过*parm.a来拷贝构造一个新的A对象,而不是傻乎乎地直接复制指针。这样不管以后A类加多少成员,你都不用修改B的拷贝逻辑——A的拷贝构造会自动处理所有成员的复制。
修改后的B类代码如下:
class B { public: A *a; B() { a = new A(10); } // 拷贝构造:创建新的A对象,用parm的A实例初始化 B(const B& parm) { a = new A(*parm.a); } // 赋值运算符:先释放当前A,再拷贝新的A B& operator = (const B& parm) { if (this != &parm) { delete a; // 先释放当前持有的A,避免内存泄漏 a = new A(*parm.a); } return *this; } ~B() { delete a; } };
这样改完之后,每个B实例都会拥有完全独立的A对象,析构时也不会出现重复释放内存的崩溃问题。
方法二:用智能指针简化内存管理(更推荐)
如果你的项目用的是C++11及以上标准,强烈建议用std::unique_ptr来管理A的指针。智能指针会自动处理内存释放,而且默认禁止浅拷贝(直接拷贝unique_ptr会编译报错),逼你实现正确的深拷贝逻辑,同时代码还更简洁:
#include <memory> // 记得包含智能指针的头文件 class B { public: std::unique_ptr<A> a; B() : a(std::make_unique<A>(10)) {} // 拷贝构造:用parm的A实例拷贝构造新对象,交给unique_ptr管理 B(const B& parm) : a(std::make_unique<A>(*parm.a)) {} // 赋值运算符:直接替换为新拷贝的A对象 B& operator = (const B& parm) { if (this != &parm) { a = std::make_unique<A>(*parm.a); } return *this; } // 完全不用手动写析构函数,unique_ptr会自动释放内存 };
这种方式不仅省去了手动delete的麻烦,还能避免忘记释放内存导致的泄漏问题,代码逻辑也更清晰。
小提醒
不管用哪种方法,都要确保A类的拷贝构造函数是正确的——你现在写的A的拷贝构造已经没问题了,能正确复制data成员。以后如果A类添加了新成员,只要更新A的拷贝构造(或者让编译器生成默认的拷贝构造,只要所有成员都是可拷贝的),B类的拷贝逻辑不用改就能自动生效。
内容的提问来源于stack exchange,提问作者samnaction
相关产品推荐
相关产品推荐

