拷贝构造函数
我们先看一个普通的构造函数的使用
class Test { private: /* data */ public: Test(int a); ~Test(); int A; }; Test::Test(int a) { A = a; } Test::~Test() { } int main() { Test test(1); cout<<test.A<<endl; }
我们定义了一个类 Test 并用了类名定义了一个构造函数,用来传入成员变量A的值。
这是一个正常的构造函数的用法。
那么拷贝构造函数什么时候用呢?
当我想用一个对象去初始化另一个对象的时候。
Test A;
Test A(B);
就需要用到拷贝构造函数,我们看一下怎么写
class Test { private: /* data */ public: Test(int a); Test(const Test &q); ~Test(); int A; }; Test::Test(int a) { A = a; } Test::Test(const Test &q) { A = q.A + 1; } Test::~Test() { } int main() { Test test(1); Test test2(test); Test test3 = test; cout<<test.A<<endl; cout<<test2.A<<endl; cout<<test3.A<<endl; }
输出结果
1 2 2
代码中标红的部分,就是拷贝构造函数,和他的调用方法。为了区分 用拷贝构造函数赋值的对象,所以我给 A 加了 1 .
假设现在我有一个普通函数调用了刚创建的类,我们看一下运行结果
class Test { private: /* data */ public: Test(int a); Test(class Test &q); ~Test(); int A; }; Test::Test(int a) { A = a; } Test::Test(class Test &q) { A = q.A + 1; } Test::~Test() { } void get(Test p) { cout<<"the A int get() is : "<<p.A<<endl; } int main() { Test test(1); Test test2(test); Test test3 = test; cout<<test.A<<endl; cout<<test2.A<<endl; cout<<test3.A<<endl; get(test2); }
运行结果:
1 2 2 the A int get() is : 3
证明我们在调用 get函数,传参的时候 Test p 又重新调用了一次拷贝构造函数,所以输出的值是3
如果我要在构造函数中调用构造函数,会是什么样的结果呢?
看这样的一个例子
class Test { private: /* data */ public: Test(int a,int b); Test(int a,int b,int c); ~Test(); int A,B,C; }; Test::Test(int a,int b) { A = a; B = b; Test(a,b,100); } Test::Test(int a,int b,int c) { A = a; B = b; C = c; } Test::~Test() { /* cout<<"---------"<<endl; cout<<A<<endl; cout<<B<<endl; cout<<C<<endl; cout<<"---------"<<endl; */
} int main(void) { Test test(1,1); cout<<test.A<<endl; cout<<test.B<<endl; cout<<test.C<<endl; }
重载了构造函数并且在2个参数的构造函数中调用了3个参数的构造函数。结果会是 a = 1 b = 1 c = 100吗
输出结果如下:
1 1 30
第三个数字并非我们想要的100
我们在析构函数中加上打印,看一下输出结果
--------- 1 1 100 --------- 1 1 30 --------- 1 1 30 ---------
中间红色部分是主函数中的打印结果 1 1 30
前后两次是析构函数打印出来的,证明一开始c = 100 确实真的传入了对象当中,但是被析构函数释放掉了
也就是说在执行2个参数的构造函数中,执行了一次析构函数。
我们尽量避免不断的多次调用构造函数