拷贝构造函数是用于创建一个新对象并将其初始化为另一个对象的副本的特殊构造函数。在拷贝构造函数中,如果我们将参数作为值传递,那么会发生对象复制,这将导致无限递归的调用,因为拷贝构造函数的调用需要创建一个新对象并将其初始化为另一个对象的副本。这将导致无限循环直到栈溢出。
为了避免这种无限递归的调用,我们通常会将参数传递给拷贝构造函数的引用。这样,拷贝构造函数将使用原始对象的地址来初始化新对象,而不是创建原始对象的副本。这不仅避免了无限递归,而且可以提高程序的效率。
因此,传递引用参数是拷贝构造函数的常见做法,因为它可以避免无限递归的调用,并且可以提高程序的效率。
#include <iostream>
using namespace std;
class MyClass {
public:
int* data;
int size;
MyClass() : data(nullptr), size(0) {}
MyClass(int s) : size(s) {
data = new int[size];
for (int i = 0; i < size; i++) {
data[i] = 0;
}
}
// 拷贝构造函数
MyClass(const MyClass& other) {
size = other.size;
data = new int[size];
for (int i = 0; i < size; i++) {
data[i] = other.data[i];
}
}
~MyClass() {
if (data) {
delete[] data;
data = nullptr;
}
}
};
int main() {
MyClass obj1(3); // 创建一个包含三个元素的 MyClass 对象
obj1.data[0] = 10;
obj1.data[1] = 20;
obj1.data[2] = 30;
MyClass obj2(obj1); // 调用拷贝构造函数
cout << obj2.data[0] << endl; // 输出:10
return 0;
}
当用已存在的对象创建新对象时候,编译器会自动调用拷贝构造函数完成新对象的初始化操作。
假设该代码是成立,在值传递时候,传参期间会产生一个临时变量,当我们实例化对象d1后,将d1拷贝给d2时调用拷贝构造函数(我们的本意,最终目的),此时d1发生值传递,d1将值传递给临时对象dd1,而此时又要调用拷贝构造函数(非本意)将d1的值传递给dd1,因为是值传递,一旦调用又要产生临时变量ddd1,将d1的值传递给临时变量ddd1,那么问题就很明显了,值传递,会进行形参实例化,类类型实例化,会再调用构造函数,就会一直调用,因此结果就是无穷递归
————————————————
一句话:调用拷贝构造函数进行初始化是在实例化一个对象时自动调用的,并非我们能够直接调用的;
MyClass obj2(obj1);用MyClass 类实例对象obj2,后面的(obj1)是告诉编译器调用拷贝构造函数,值传递会不断调用构造函数,我们不能控制,因为值传递时会把obj1赋值給临时变量,并调用拷贝构造函数,不断往复。
类实例对象的方法:
对象重定义;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)