非常感激我队友大爹给我的复习资料

拷贝构造函数是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。

如果在类中没有定义构造拷贝函数,编译器会自行定义一个。如果类带有指针变量,并有动态分配内存,则它必须有一个拷贝构造函数。拷贝构造函数的最常见形式如下:

1
2
3
classname (const classname &obj) {
// 构造函数的主体
}

具体示例

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
#include <iostream>
using namespace std;

class Example{
private:
int a;
public:
// 构造函数
Example(int b) { a = b; }
// 拷贝构造函数
Example(const Example& b) { cout << "copy" << endl; }
// Example(const Example& b) { a = b.a; }
// 一般成员函数
void show();
};
void Example::show() { cout << a << endl; }

int main(void){
Example A(100);
Example B = A; // 注意, 这里的对象初始化要调用拷贝构造函数
B.show(); // output : 100
Example C(A); // 等价于 Example C = A;
C.show();
return 0;
}

/*
当自己定义的拷贝构造函数1未注释时, 输出结果为:
======================
copy
16
copy
0
=======================

函数1注释, 或改为函数2后,结果为:
=======================
100
100
=======================
*/

调用时机

拷贝构造函数通常用于:

  • 通过使用另一个同类型的对象来初始化新创建的对象
  • 复制对象把它作为参数传递给函数
  • 复制对象,并从函数返回这个对象

定义如下类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Example{
private:
int a;
public:
// 构造函数
Example(int b) : a(b){
cout << "create: " << a << endl;
}
// 拷贝构造函数
Example(const Example & B){
a = B.a;
cout << "copy" << endl;
}
// 析构函数
~Example(){
cout << "destroy" << endl;
}
void show(){
cout << a << endl;
}
};

作为参数传递给函数

以下主函数运行结果为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void g_Func(Example C){
cout << "test: ";
C.show();
}

int main(void){
Example test(1);
// 传入对象
g_Func(test);
return 0;
}

/*
该程序的输出结果为:
===================
create: 1
copy
test: 1
destroy
destroy
===================
*/

对象通过另一个对象初始化

以下主函数运行结果为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main(void){
Example A(100);
Example B(A);
Example C = A;

return 0;
}

/*
该程序的输出结果为:
===================
create: 100
copy
copy
destroy
destroy
destroy
===================
*/

作为返回值

以下主函数运行结果为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Example h_Func(){
Example temp(2);
return temp;
}

int main(void){
Example h = h_Func();
// Example h(2);
return 0;
}
/*
=============
create: 2
destroy
=============
*/

虽然没有输出“copy”,但是还是调用拷贝函数了的。具体原因是RVO,被G++进行值返回的优化了。