2009-10-01 9 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(); 
     } 
}; 

Si oui Dérivé d1; Dérivé d2 = d1; Le constructeur de copie de base est appelé et le constructeur de copie par défaut de derived est appelé. Mais si je supprime les commentaires du constructeur de copie de dérivées, le constructeur de copie de base n'est pas appelé. Y a-t-il une raison spécifique à cela? Merci d'avance.Constructeur de copie de base non appelé

+3

IMVHO http://www.parashift.com/c++-faq-lite/ctors.html est une ressource géniale pour comprendre les constructeurs C++. (Et en fait, la FAQ C++ Lite en général est une source incroyable d'informations pour le débutant avancé.) – notJim

+0

Je pense que le destructeur de base devrait être virtuel. –

Répondre

13

Si vous voulez lire la règle réelle, vous devez vous référer à la norme C++ 12,8/8:

Le constructeur de copie implicitement défini pour la classe X effectue une copie de ses sous-objets membre à membre. L'ordre de copie est le même que l'ordre d'initialisation des bases et des membres dans une construction définie par l'utilisateur (voir 12.6.2). Chaque sous-objet est copié de la manière appropriée à son type:

  • si le sous-objet est de type classe, le constructeur de copie de la classe est utilisé;
  • si le sous-objet est un tableau, chaque élément est copié, de la manière appropriée au type d'élément;
  • si le sous-objet est de type scalaire, l'opérateur d'affectation intégré est utilisé.

Lorsque vous définissez constructeur de copie explicitement que vous devez appeler copie c-tor de classe de base explicitement.

16

Je pense que vous devez appeler explicitement le constructeur de copie de base:

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

Dans votre Derived constructeur de copie, vous devez ajouter ce qui suit:

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

C++ ne fait aucune sorte de "correspondance du constructeur". Si vous n'appelez pas explicitement le constructeur de la classe de base, celui par défaut est appelé (bien, techniquement, le sous-objet de la classe de base est "value initialized", mais pour les classes avec constructeurs c'est la même chose).

1

vous devriez lire this: il explique comment l'héritage & membres spéciaux aiment les constructeurs travaillent.

0

Merci beaucoup. Je l'ai. Cela signifie que l'appel au constructeur de copie de la classe de base est effectué automagivement dans le constructeur de copie par défaut du dérivé. Alors que dans le second cas, puisque j'écris le constructeur de copie du dérivé, je dois faire un appel explicite au constructeur de copie de la base. Merci encore

Questions connexes