C++基础笔记(7):拷贝构造函数

C++基础笔记(7):拷贝构造函数 在 C 面向对象编程中构造函数负责对象的创建而拷贝构造函数则专门处理对象的“复制式创建”。当我们使用已有对象去初始化一个新对象或者在函数参数传递与返回对象时发生值传递时拷贝构造函数就会被自动调用。它本质上是一种特殊的构造函数用于保证新对象能够正确地复制原对象的状态与资源而不是简单地进行位级复制。1. 基本概念拷贝构造函数Copy Constructor是一种特殊的构造函数它用于使用一个已有对象来初始化同类型的新对象。与普通构造函数不同拷贝构造函数的参数是该类对象本身的引用其主要作用是完成对象状态的复制使新对象在创建时就拥有与原对象相同的数据内容。拷贝构造函数通常用于通过使用另一个同类型的对象来初始化新创建的对象。复制对象把它作为参数传递给函数。复制对象并从函数返回这个对象。如果在类中没有定义拷贝构造函数编译器会自行定义一个。如果类带有指针变量并有动态内存分配则它必须有一个拷贝构造函数。拷贝构造函数的最常见形式如下classname (const classname obj) { // 构造函数的主体 }其中参数通常使用const引用这是因为一方面避免产生新的临时对象否则会递归调用拷贝构造函数另一方面保证原对象不会被修改。下面的示例展示了按值传递对象时自动触发拷贝构造函数的情况#include iostream using namespace std; class Demo { public: Demo() { cout 默认构造函数\n; } Demo(const Demo d) { cout 拷贝构造函数\n; } }; void func(Demo d) // 按值传参 { cout 进入函数\n; } int main() { Demo d1; func(d1); // 传值调用产生临时对象触发拷贝构造 }在调用func(d1)时编译器会先创建一个临时对象d用d1初始化它因此拷贝构造函数被调用一次。类似地当函数返回对象时也会发生同样的复制过程尽管现代编译器常通过返回值优化 RVO 省略拷贝。2. 浅拷贝与深拷贝拷贝构造函数可以通过对象复制的两种实现方式浅拷贝Shallow Copy与深拷贝Deep Copy进行分类。它们的核心区别在于是否复制对象所拥有的资源本身。2.1. 浅拷贝浅拷贝是一种最简单的对象复制方式。 默认生成的拷贝构造函数和拷贝赋值运算符通常采用的就是浅拷贝策略 。这种方式在对象不涉及资源管理时是安全且高效的但在涉及动态内存时会带来隐患。浅拷贝的特点在于仅复制成员变量的值而不复制成员变量所指向的资源本身。若对象内部包含指针那么复制后多个对象将指向同一块内存区域资源被共享。下面示例演示浅拷贝的行为#include iostream using namespace std; class ShallowCopy { public: int* data; ShallowCopy(int value) { data new int(value); } // 浅拷贝构造函数 ShallowCopy(const ShallowCopy other) { data other.data; // 仅复制指针地址 } ~ShallowCopy() { delete data; } }; int main() { ShallowCopy a(10); ShallowCopy b a; // 浅拷贝 cout *a.data *b.data endl; }在这个例子中a和b的data指针指向同一块内存。当其中一个对象析构释放资源后另一个对象仍然持有该地址再次释放时就会产生未定义行为。这正是浅拷贝最大的问题资源共享导致生命周期冲突。2.2. 深拷贝深拷贝则是在复制对象时不仅复制成员变量的值还会复制对象所拥有的资源本身为新对象创建一份独立的资源副本。这样每个对象都拥有自己的数据不会互相影响从而保证资源管理的安全性。对于包含指针或动态内存的类通常需要手动实现深拷贝否则默认拷贝可能造成严重错误。下面示例展示深拷贝的实现方式#include iostream using namespace std; class DeepCopy { public: int* data; DeepCopy(int value) { data new int(value); } // 深拷贝构造函数 DeepCopy(const DeepCopy other) { data new int(*(other.data)); // 创建新的内存副本 } ~DeepCopy() { delete data; } }; int main() { DeepCopy a(20); DeepCopy b a; // 深拷贝 cout *a.data *b.data endl; }在深拷贝中a与b的data指向不同的内存地址即使其中一个对象被销毁另一个对象仍然保持有效。这种方式确保了对象之间的数据独立性是处理动态资源类时的标准做法。2.3. 深拷贝与浅拷贝的关键区别从本质上看浅拷贝与深拷贝的区别在于资源是否独立。浅拷贝复制的是“指向资源的地址”而深拷贝复制的是“资源本身”。因此浅拷贝实现简单、效率高但可能引发资源冲突深拷贝实现复杂需要额外的内存分配与释放但安全可靠 。如果类涉及动态内存、文件、网络连接或其他独占资源通常必须实现深拷贝并同时提供正确的拷贝赋值运算符和析构函数以保证资源生命周期管理的一致性。