拷贝构造函数

 类进行拷贝初始化时会调用拷贝构造函数,拷贝初始化发生在以下几种情况中:

[1] 有“=”的地方会发生拷贝;

[2] 将一个对象作为参数传递给一个非引用的对象时;

[3] 从一个返回类型为引用的类型的函数返回一个对象;

[4] 用花括号初始化一个数组中的元素;

拷贝构造函数的形参必须为引用类型,我认为应该有两点原因:

1. 在类的类部定义该类的对象,只能定义为引用类型或指针类型,因为其属于不完全类型;

2. 如果不定义为引用就会陷入无限的循环——调用拷贝构函数,必须拷贝它的实参,而拷贝它的实参就要调用拷贝构造函数

 

根据下面的实例我们来分析一下拷贝构造函数的调用,大家可以先自己思考一下程序的输出是什么?

 1 #include <iostream>
 2 #include <cmath>
 3 using namespace std;
 4 class Point
 5 {
 6 public:
 7     Point(int xx = 0, int yy = 0)
 8     {
 9         x = xx;
10         y = yy;
11         cout << "calling the constructor of point" << endl;
12     }
13 
14     Point(const Point & p)
15     {
16         x = p.x;
17         y = p.y;
18         cout << "calling the copy constructor of point" << endl;
19     }
20 
21     int getx() const
22     {
23         return x;
24     }
25 
26     int gety() const
27     {
28         return y;
29     }
30 private:
31     int x, y;
32 };
33 
34 class Line
35 {
36 public:
37     Line(Point pa, Point pb)
38         :p1(pa), p2(pb)
39     {
40         cout << "calling the constructor of Line" << endl;
41         double x = static_cast<double>(p1.getx() - p2.getx());
42         double y = static_cast<double>(p1.gety() - p2.gety());
43         len = sqrt(x*x +y*y);
44     }
45 
46     Line(const Line & L)
47         :p1(L.p1), p2(L.p2)
48     {
49         len = L.len;
50         cout << "calling the copy constructor of Line" << endl;
51     }
52 
53     double getLen() const
54     {
55         return len;
56     }
57 private:
58     Point p1, p2;
59     double len;
60 };
61 
62 
63 int main()
64 {
65     Point myp1(1, 1), myp2(4, 5);
66     Line L1(myp1, myp2);
67     Line L2(L1);
68     cout << "the lenth of L1 is" << L1.getLen() << endl;
69     cout << "the lenth of L2 is" << L2.getLen() << endl;
70     return 0;
71 }

第65行程序,定义了两个Point对象,采用直接初始化,因此会调用两次Point的构造函数;

第66行程序,定义了一个Line对象,采用直接初始化,因此会调用Line的构造函数,但是在调用Line的构造函数之前调用了4次Point的拷贝构造函数,为什么会这样呢?

第一次:myp1作为实参传递给Line的构造函数发生一次拷贝;

第二次:myp2作为实参传递给line的构造函数发生一次拷贝;

第三次:myp1拷贝初始化Line的p1数据成员时发生一次拷贝;

第四次:myp2拷贝初始化Line的p2数据成员时发生一次拷贝;

第67行程序,定义了一个Line的对象,采用拷贝初始化,因此需要调用Line的拷贝构造函数,但是在调用LIne的拷贝构造函数之前,调用了两次Point的拷贝构造函数,这是因为:

46     Line(const Line & L)
47         :p1(L.p1), p2(L.p2)

用L.p1初始化p1是发生一次拷贝,同理p2也发生了相同的拷贝,因此调用了两次Point的拷贝构造函数。

 

posted @ 2016-11-11 22:51  oscarwin  阅读(278)  评论(0编辑  收藏  举报