未调用基本复制构造函数

时间:2009-10-01 04:44:08

标签: c++ inheritance

class Base
{
      public:
      int i;

      Base()
      {
          cout<<"Base Constructor"<<endl;
      }

      Base (Base& b)
      {
          cout<<"Base Copy Constructor"<<endl; 
          i = b.i; 
      }


      ~Base()
      {
          cout<<"Base Destructor"<<endl;
      }

      void val()
      {
             cout<<"i: "<< i<<endl;
      }      
};

class Derived: public Base
{
      public:
      int i;

      Derived()
      {
          Base::i = 5;     
          cout<<"Derived Constructor"<<endl;
      }

      /*Derived (Derived& d)
      {
          cout<<"Derived copy Constructor"<<endl;
          i = d.i; 
      }*/

      ~Derived()
      {
          cout<<"Derived Destructor"<<endl;
      }      

      void val()
      {
             cout<<"i: "<< i<<endl;
             Base::val();
      }
};

如果我这样做 衍生d1; 派生d2 = d1; 调用base的拷贝构造函数,调用派生的默认拷贝构造函数。

但是如果我从derived的复制构造函数中删除注释,则不会调用基本复制构造函数。这有什么具体原因吗? 提前谢谢。

6 个答案:

答案 0 :(得分:16)

我认为你必须显式调用基本拷贝构造函数:

  Derived (Derived& d) : Base(d)
  {
      cout<<"Derived copy Constructor"<<endl;
      i = d.i; 
  }

答案 1 :(得分:13)

如果您想阅读实际规则,请参阅C ++标准12.8 / 8:

  

X类的隐式定义的复制构造函数执行其子对象的成员复制。该   复制顺序与用户定义的构造中基础和成员的初始化顺序相同   tor(见12.6.2)。每个子对象都以适合其类型的方式复制:

     
      
  • 如果子对象是类类型,则使用该类的复制构造函数;
  •   
  • 如果子对象是一个数组,则以适合于元素类型的方式复制每个元素;
  •   
  • 如果子对象是标量类型,则使用内置赋值运算符。
  •   

当您明确定义复制构造函数时,应该显式调用基类的复制c-tor。

答案 2 :(得分:4)

Derived复制构造函数中,您需要添加以下内容:

Derived (const Derived &d) : Base(d) { }

答案 3 :(得分:2)

C ++没有做任何类型的“构造函数匹配”。如果没有显式调用基类构造函数,则调用默认的构造函数(从技术上讲,基类子对象是“值初始化”,但对于带有构造函数的类,这是相同的事情。)

答案 4 :(得分:1)

你应该阅读this:它解释了遗产和遗传的关系。像建设者这样的特殊成员正在努力。

答案 5 :(得分:0)

非常感谢你。我知道了。这意味着对基类复制构造函数的调用是在派生的默认复制构造函数中自动完成的。在第二种情况下,因为我正在编写派生的复制构造函数,所以我必须对base的复制构造函数进行显式调用。再次感谢