解释构造函数和复制构造函数示例

时间:2016-09-01 14:35:56

标签: c++

我有这个代码,我可以理解Fat类承包商发生了什么。

#include <iostream>
using namespace std;
class Block{ 
  int data;
public:
  Block(int i = 10) : data(i){ 
    cout << "I just created a Block " << endl; 
  }
  ~Block() {
    cout << "I will destroy a Block with " << data << endl; 
  }
  void inc() { 
    data++; 
  } 
};

class A{ 
  Block& block1; 
  Block block2;
  public:
    A(Block& blk) : block1(blk), block2(blk) { 
      cout << "I just created an A " << endl; 
    }

    A(const A& a): block1(a.block1), block2(a.block2) {
      cout << "I just created an A by copying but I will also do bad things" << endl;
      block1.inc(); block2.inc(); 
    }
    ~A() { 
      cout << "I will destroy an A " << endl; 
    }

    void inc() { 
      block1.inc(); block2.inc(); 
    } 
  };

class Fat{ 
  A  a; 
  A& ra; 
  A*  pa;
public:
  Fat(A& da) : a(da),ra(da) { 
    pa = new A(da);
    cout << "Fat just created !" << endl;
  }
  ~Fat() {  
    delete pa;
    cout << "Fat to be destroyed !" << endl; 
  }
    void inc() { 
      a.inc(); 
      ra.inc(); 
      pa->inc(); 
    }
  };

int main(){ 
  Block block;
  A a(block); 
  Fat fat(a);
  fat.inc();
  return 0; 
}

以及结果:

I just created a Block 
I just created an A 
I just created an A by copying but I will also do bad things
I just created an A by copying but I will also do bad things
Fat just created !
I will destroy an A 
I will destroy a Block with 12
Fat to be destroyed !
I will destroy an A 
I will destroy a Block with 12
I will destroy an A 
I will destroy a Block with 11
I will destroy a Block with 15

为什么复制构造函数会运行两次?

2 个答案:

答案 0 :(得分:2)

第一个"I just created an A by copying but I will also do bad things"来自这一行:

Fat(A& da) : a(da), ra(da) {

a(da)这个人称之为A的复制构造函数

来自类fat的构造函数的秒数:

Fat(A& da) : a(da), ra(da) {
    pa = new A(da); //HERE!!
    cout << "Fat just created !" << endl;
}

再次使用pa = new A(da);调用A的复制构造函数。

编辑:感谢您格式化代码

答案 1 :(得分:0)

第一个副本用于初始化a中的Fat成员变量:

Fat(A& da) : a(da), ra(da) {

然后就行了

pa = new A(da);

通过复制A在免费商店上创建da的新实例,因此它会调用复制构造函数。如果您想要创建指向A的现有实例的指针,则应编写

pa = &da;