2009-10-01 33 views
5
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的默认拷贝构造函数。未调用的基本复制构造函数

但是,如果我从派生的复制构造函数中删除注释基本副本构造函数不会被调用。这有什么特别的原因吗? 在此先感谢。

+3

IMVHO http://www.parashift.com/c++-faq-lite/ctors.html是理解C++构造函数的极好资源。 (实际上,C++ FAQ Lite通常是高级初学者的一个难以置信的信息源。) – notJim 2009-10-01 04:53:17

+0

我认为你的基础析构函数应该是虚拟的。 – 2013-09-08 18:52:19

回答

13

如果你想读的实际规则,你应该参考C++标准12.8/8:

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

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

当你定义拷贝构造函数明确你应该调用基类的拷贝C-TOR明确。

16

我认为你必须明确地调用基复制构造函数:

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

在你Derived拷贝构造函数,你需要添加以下内容:

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

C++不做任何形式的“构造函数匹配”。如果你没有明确地调用基类的构造函数,那么调用默认的构造函数(在技术上,基类子对象是“值初始化的”,但对于具有构造函数的类来说,这是相同的事情)。

1

您应该阅读this:它解释了继承&特殊成员(如构造函数)是如何工作的。

0

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