在 C++ 中,请解释深拷贝与浅拷贝的核心区别,并给出一个规范的拷贝构造函数实现示例。
考察说明
考查对 C++ 拷贝语义的理解及拷贝构造函数的正确实现。
回答思路
- 【回答框架 1】浅拷贝指按成员逐位复制,当类含有指针或动态资源时,多个对象会共享同一块内存,析构时可能导致重复释放或悬空指针。
- 【回答框架 2】深拷贝为每个对象分配独立的资源副本,拷贝构造函数中通过 new 等操作复制指针指向的数据,确保各自拥有独立内存,析构互不影响。
- 【回答框架 3】标准拷贝构造函数写法:class A { int* p; public: A(const A& other) : p(new int(*other.p)) {} }; 同时需考虑自赋值、异常安全及资源释放。
- 【回答框架 4】对于更复杂的类,还应遵循三之法则,即显式定义拷贝构造函数、拷贝赋值运算符和析构函数,必要时使用移动语义避免不必要的深拷贝。
- 【回答框架 5】实际工程中可优先使用智能指针(如 unique_ptr 或 shared_ptr)管理资源,以减少手动拷贝和释放的错误。
- 【关键点 1】浅拷贝只复制指针值,深拷贝复制指针所指的数据。
- 【关键点 2】深拷贝构造函数必须为指针成员分配新内存并复制内容。
- 【关键点 3】实现深拷贝需配合析构函数和拷贝赋值运算符,遵守三之法则。
- 【关键点 4】使用智能指针可简化资源管理,减少手动深拷贝需求。
- 【关键点 5】拷贝赋值运算符需处理自赋值和异常安全,通常采用 copy-and-swap 技巧。
- 【易错点 1】只写拷贝构造函数而忽略拷贝赋值运算符,仍可能发生浅拷贝。
- 【易错点 2】拷贝构造函数中直接使用 memcpy 或按位复制指针成员属于浅拷贝,会导致双重释放。
- 【易错点 3】未考虑自赋值时,拷贝赋值运算符可能释放自身内存,导致悬挂指针。