C++中的拷贝构造函数在下面哪些情况下会被调用( BCD )?
A. 对象创建的时候
B. 使用一个类的对象去初始化该类的一个新对象
C. 被调用函数的形参是类的对象
D. 当函数的返回值是类的对象时,函数执行完成返回调用者
什么情况下系统会调用拷贝构造函数?
- 用类的一个对象去初始化另一个对象时;
- 当函数的形参是类的对象时,即值传递时,引用传递则不会调用;
- 当函数的返回值是类的对象或引用时。
拷贝构造函数的调用实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| #include <iostream> using namespace std;
class A { int a; public: A(int a) : a(a) {} A(const A& obj) { a = obj.a; cout << "A(const A& obj)"; } int geta() { return a; } };
int geta_byVal(A obj) { return obj.geta(); }
int geta_byRef(A& obj) { return obj.geta(); }
A ret_Aval(A& obj) { return obj; }
A& ret_Aref(A& obj) { return obj; }
int main() { A obj1(1); cout << "A obj2(obj1): "; A obj2(obj1); cout << endl; cout << "A obj3 = obj1: "; A obj3 = obj1; cout << endl; cout << "int geta_byVal(A obj): "; int a = geta_byVal(obj1); cout << endl; cout << "int geta_byRef(A& obj): "; a = geta_byRef(obj1); cout << endl; cout << "A ret_Aval(A& obj): "; A obj4 = ret_Aval(obj1); cout << endl; cout << "A& ret_Aref(A& obj): "; A obj5 = ret_Aref(obj1); cout << endl; return 0; }
|
从运行结果来看,当我们用类的一个对象去初始化另一个对象时(直接拷贝构造或赋值构造),都会调用拷贝构造函数;当函数的形参是值传递时,会调用拷贝构造函数,而引用传递不会;已知引用传递不会调用拷贝构造函数,我们传入类对象的引用并将它返回,可以看出当函数的返回值是类的对象或引用时,都会在返回时调用拷贝构造函数。
进一步测试发现,当函数返回值为右值引用时(return move(obj);),如果实现了移动拷贝构造,就会调用移动拷贝构造;如果只实现了复制拷贝构造,则会调用复制拷贝构造。当然也可以直接调用移动拷贝构造函数。下面为补充实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| A(A&& obj) { a = obj.a; cout << "A(A&& obj)"; }
A&& retArefRight() { A t(1); return move(t); }
cout << "A&& retArefRight(): "; A obj6 = retArefRight(); cout << endl;
cout << "A(move(obj6)): "; A obj7 = A(move(obj6)); cout << endl;
|
参考
调用拷贝构造函数的几种情况