关于复制构造函数的几个问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于复制构造函数的几个问题相关的知识,希望对你有一定的参考价值。
一、什么是复制构造函数
复制构造函数是一种特殊的构造函数,其形参是本类对象的引用,作用是完成同类对象之间的复制。一般情况下编译器生成一个默认的复制构造函数不需要我们考虑,但有些情况下,默认的复制构造函数无法提供完整的功能,这时就需要我们自己来编写实现。复制构造函数形式如下:
//假如类名是Test class Test { public: Test(){} /*复制构造的形参是通过引用传递的,
因为如果不用引用就是使用值传递,
会调用复制构造函数,形成一个矛盾!
*/ Test(const Test& src) { a = src.a; b = src.b } ~Test(){} private: int a; float b; };
二、哪些情况调用了复制构造函数
Test a; // 调用构造函数 Test b = a; // 调用复制构造函数 Test c(a); // 调用复制构造函数 // 函数形式参数为对象本身(非指针或引用) void func(Test _a){...} func(a); // 函数返回值为对象本身 Test func(){...} Test a; a = func();
三、什么时候需要自己编写复制构造函数
根据三五法则,当你的析构函数不为空时就应当自己编写复制构造函数。
看下面这个例子
1 //test.h 2 class Test 3 { 4 public: 5 Test() 6 { 7 p = new int(1); 8 cout << "constructor: "<<*p << endl; 9 } 10 Test(const Test& src) 11 { 12 p = new int(1); 13 *p = *(src.p); 14 cout <<"copy constructor: "<< *p << endl; 15 16 } 17 18 const Test& operator=(const Test& src) 19 { 20 p = new int; 21 *p = *(src.p); 22 cout << "operator" << endl; 23 return *this; 24 } 25 ~Test() 26 { 27 delete p; 28 cout << "deconstructor: " <<endl; 29 } 30 31 private: 32 int* p; 33 }; 34 35 //test.cpp 36 int main() 37 { 38 Test a; 39 Test b = a; 40 a = b; 41 vector<Test> v; 42 //push_back两个对象下面就会报错!Why?? 43 v.push_back(b); 44 v.push_back(a); 45 46 auto it = v.begin(); 47 v.erase(it); 48 return 0; 49 cout << v.size() << endl; 50 51 return 0; 52 }
四、重载赋值运算符
上面的程序中有一个坑,当vector删除元素时调用erase函数,其中可能会在内部调用赋值运算符;而默认的赋值运算符也不能满足需求(原理同复制构造函数),所以我们不仅要编写复制构造函数还要重载赋值运算符。
1 const Test& operator=(const Test& src) 2 { 3 ... 4 //内容同复制构造函数 5 ... 6 return *this; 7 }
总结
当析构函数不为空时,一定要编写好复制构造函数,并重载赋值运算符!你永远不知道什么时候就用到它们了。。。
以上是关于关于复制构造函数的几个问题的主要内容,如果未能解决你的问题,请参考以下文章