调用拷贝构造函数的几种情况
当类中成员有指针变量、类中有动态内存分配时常常需要用户自己定义拷贝构造函数。
在什么情况下系统会调用拷贝构造函数:
(1)用类的一个对象去初始化另一个对象时 (2)当函数的形参是类的对象时(也就是值传递时),如果是引用传递则不会调用 (3)当函数的返回值是类的对象或引用时
代码示例:
class Test
{
public:
int a;
Test(int i):a(i)
{
cout<<a<<'\t' << "构造函数" << endl;
}
~Test()
{
cout<<a<<'\t' << "析构函数"<<endl;
}
Test(const Test &b)
{
a = b.a;
cout << b.a <<'\t'<< "拷贝构造函数" << endl;
}
};
int main()
{
Test a(10);
Test b(20);
Add(a, b);
}
调用函数为值传递
Test Add(Test a, Test b)
{
auto res = Test(a.a + b.a);
return res;
}
输出为
| 输出 | 解释 |
|---|---|
| 10 构造函数 | |
| 20 构造函数 | a,b初始化 |
| 20 拷贝构造函数 | |
| 10 拷贝构造函数 | 形参的拷贝构造,右到左 |
| 30 构造函数 | Test(a.a + b.a)临时对象 |
| 30 拷贝构造函数 | 赋值给res |
| 30 析构函数 | Test(a.a + b.a)临时对象析构 |
| 10 析构函数 | |
| 20 析构函数 | 形参析构 |
| 30 析构函数 | 返回值res的析构函数 |
| 20 析构函数 | |
| 10 析构函数 | a,b析构函数 |
参数为引用传递
Test Add(Test& a, Test& b)
{
auto res = Test(a.a + b.a);
return res;
}
| 输出 | 解释 |
|---|---|
| 10 构造函数 | |
| 20 构造函数 | a,b 初始化 |
| 30 构造函数 | Test(a.a + b.a)临时变量初始化 |
| 30 拷贝构造函数 | res的复制构造(值传递) |
| 30 析构函数 | 临时对象析构 |
| 30 析构函数 | res析构 |
| 20 析构函数 | |
| 10 析构函数 | a,b析构 |
返回值为引用
Test& Add(Test& a, Test& b)
{
auto res = Test(a.a + b.a);
return res;
}
| 输出 | 解释 |
|---|---|
| 10 构造函数 | |
| 20 构造函数 | |
| 30 构造函数 | res 是 临时对象的引用,因此不会拷贝构造 |
| 30 析构函数 | |
| 20 析构函数 |
相关阅读
- C++ 初始化列表
- 一种编译期 Map 的实现
- Most Vexing Parse 10 析构函数|