拷贝构造函数剖析

拷贝构造函数

知识点

解释:拷贝构造函数是一种特殊的构造函数,它具有一般构造函数的所有特性,但其形参是本类对象的引用

作用:使用一个已经存在的对象(由拷贝构造函数参数指定)去初始化同类的一个新对象

定义格式:构造函数名 (&类名);

三种使用情况

  1. 用一个对象去初始化同类的另一个对象;
  2. 函数的形参是类的对象,调用函数时形参与实参的结合;
  3. 函数返回值是类的对象,函数执行返回调用;

注意

  1. 拷贝构造函数的参数采用引用方式。若把一个真实的类对象作为参数传到拷贝构造函数,引起无穷递归;
  2. 拷贝构造函数的名字必须与类名相同,且无返回值;
  3. 拷贝构造函数只有一个参数,必须为本类对象的引用;
  4. 每一个类必须有一个拷贝构造函数。若用户定义类时未给出拷贝构造函数,则系统会自动产生一个缺省的拷贝构造函数;

实例

该例重点阐述:为什么拷贝构造函数的参数必须为同类对象的引用?

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

class Complex {
private:
double real, image;
public:
Complex(double r, double i); //声明构造函数
Complex(Complex &c); //声明拷贝构造函数
Complex add(Complex c);
void Output();
};

Complex::Complex(double r, double i): real(r), image(i) { //构造函数初始化列表
cout << "调用两个参数的构造函数" << endl;
}

Complex::Complex(Complex &c) {
real = c.real;
image = c.image;
cout << "调用拷贝构造函数" << endl;
}

void Complex::Output() {
cout << "(" << real << "," << image << ")" << endl;
}

Complex Complex::add(Complex c) {
Complex y(real + c.real, image + c.image);
return y;
}

void f(Complex n) {
cout << "n=";
n.Output();
}

int main() {
Complex a(3.0, 4.0), b(5.6, 7.9); //创建Complex类的两个对象a,b
Complex c(a); //使用拷贝构造函数,用已创建的对象a初始化要建立的另一个对象c
cout << "a=";
a.Output();
cout << "c=";
c.Output();
f(b);
c = a.add(b);
c.Output();
}

程序运行结果

1
2
3
4
5
6
7
8
9
10
调用两个参数的构造函数
调用两个参数的构造函数
调用拷贝构造函数
a=(3,4)
c=(3,4)
调用拷贝构造函数
n=(5.6,7.9)
调用拷贝构造函数
调用两个参数的构造函数
(8.6,11.9)
  1. 本例中,当程序执行到main()函数 Complex c(a); 语句时,程序会到拷贝构造函数完成“用存在的类对象a,初始化c的工作”。但是,若此时拷贝构造函数的参数是一个真实的类对象而非同类对象的引用,则无法完成对类对象c的初始化工作
  2. 因为没有一块儿内存空间去接收传递的对象,&c就相当于是a的一个别称,该临时对象用于完成对c的赋值,拷贝构造函数定义中 real=c.real; real就是c的实部,c.real就是用a的实部去给c的实部赋值,虚部部分同理,所以会无限次调用该函数,即引起无穷递归