C++ 拷贝构造函数
拷贝构造函数是一个 重载 的构造函数,用于从另一个对象声明和初始化一个对象。
拷贝构造函数有两种类型
- 默认拷贝构造函数: 编译器定义了默认的拷贝构造函数。如果用户没有定义拷贝构造函数,编译器会提供默认的构造函数。
- 用户自定义构造函数: 程序员定义了用户自定义的构造函数。
用户自定义复制构造函数的语法
考虑以下情况:
在上述情况下,
可以通过以下方式调用复制构造函数:
让我们看一个拷贝构造函数的简单示例。
// 拷贝构造函数的程序。
输出:
当调用复制构造函数时
复制构造函数在以下情况下被调用:
- 当我们用同一类别的另一个现有对象初始化对象时。例如,Student s1 = s2,其中Student是类别。
- 当同一类别的对象以按值方式作为参数传递时。
- 当函数通过按值方式返回同一类别的对象时。
构造函数产生两种类型的拷贝
- 浅拷贝
- 深拷贝
浅拷贝
- 默认的复制构造函数只能产生浅拷贝。
- 浅拷贝被定义为通过复制所有成员变量的数据来创建对象的过程。
让我们通过一个简单的例子来理解:
输出:
在上述情况下,程序员没有定义任何构造函数,因此,语句 Demo d2 = d1; 调用了编译器定义的默认构造函数。默认构造函数创建了现有对象的精确副本或浅拷贝。因此,两个对象的指针p都指向相同的内存位置。因此,当一个字段的内存被释放时,另一个字段的内存也会自动被释放,因为两个字段都指向同一个内存位置。这个问题通过 用户定义的构造函数 来解决,该构造函数创建了 深拷贝 。
深拷贝
深拷贝动态分配了副本的内存,然后复制了实际值,源对象和副本都有不同的内存位置。这样,源对象和副本是不同的,不会共享同一内存位置。深拷贝要求我们编写用户定义的构造函数。
让我们通过一个简单的例子来理解。
输出:
复制构造函数和赋值操作符(=)的区别
复制构造函数 | 赋值运算符 |
---|---|
这是一个重载的构造函数。 | 这是一个位运算符。 |
它使用已有对象初始化新对象。 | 它将一个对象的值赋给另一个对象。 |
复制构造函数的语法: Class_name(const class_name &object_name) { // 构造函数的内容 } | 赋值运算符的语法: Class_name a,b; b = a; |
复制构造函数 在用已有对象初始化新对象时被调用。 对象作为参数传递给函数。 它返回对象。 |
赋值运算符 在将已有对象赋给新对象时被调用。 |
现有对象和新对象共享不同的内存位置。 | 现有对象和新对象共享相同的内存位置。 |
如果程序员没有定义复制构造函数,编译器将自动生成隐式的默认复制构造函数。 | 如果我们没有重载“=”运算符,将发生位复制。 |