【问题标题】:Base Copy constructor not called未调用基本复制构造函数
【发布时间】:2009-10-01 04:44:08
【问题描述】:
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的默认拷贝构造函数。

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

【问题讨论】:

  • IMVHO parashift.com/c++-faq-lite/ctors.html 是了解 C++ 构造函数的绝佳资源。 (事实上​​,对于高级初学者来说,C++ FAQ Lite 是一个令人难以置信的信息来源。)
  • 我认为你的基础析构函数应该是虚拟的。

标签: c++ inheritance


【解决方案1】:

我认为您必须显式调用基本副本构造函数:

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

【讨论】:

    【解决方案2】:

    如果您想阅读实际规则,您应该参考 C++ Standard 12.8/8:

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

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

    当你显式定义拷贝构造函数时,你应该显式调用基类的拷贝c-tor。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

        C++ 不做任何类型的“构造函数匹配”。如果您没有显式调用基类构造函数,则会调用默认的构造函数(好吧,从技术上讲,基类子对象是“值初始化的”,但对于具有构造函数的类,这也是一样的)。

        【讨论】:

          【解决方案5】:

          您应该阅读this:它解释了继承和构造函数等特殊成员的工作原理。

          【讨论】:

            【解决方案6】:

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2011-03-11
              • 2012-02-06
              • 2012-02-28
              • 2013-06-23
              • 2015-11-16
              • 2017-04-13
              相关资源
              最近更新 更多