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

Se lo faccio Derivato d1; Derivato d2 = d1; Viene chiamato il costruttore di copie di base e viene chiamato il costruttore di copie predefinito di derivato.Base Copy constructor non chiamato

Ma se rimuovo i commenti dal costruttore di copia di derivato, il costruttore di base copia non viene chiamato. C'è qualche ragione specifica per questo? Grazie in anticipo.

+3

IMVHO http://www.parashift.com/c++-faq-lite/ctors.html è una risorsa eccezionale per comprendere i costruttori di C++. (E in effetti, il C++ FAQ Lite in generale è un'incredibile fonte di informazioni per i principianti avanzati.) – notJim

+0

Penso che il tuo distruttore di base debba essere virtuale. –

risposta

13

Se si desidera leggere regola attuale è necessario fare riferimento a C++ standard 12,8/8:

Il costruttore di copia implicitamente definito per la classe X esegue una copia membro a membro dei suoi oggetti secondari. L'ordine di copia è uguale all'ordine di inizializzazione di basi e membri in un costrutto definito dall'utente (vedere 12.6.2). Ogni oggetto secondario viene copiato nel modo appropriato al suo tipo:

  • se il sottobject è di tipo classe, viene utilizzato il costruttore di copie per la classe;
  • se il sottooggetto è una matrice, ogni elemento viene copiato, nel modo appropriato al tipo di elemento;
  • se il sottooggetto è di tipo scalare, viene utilizzato l'operatore di assegnazione incorporato.

Quando si definisce costruttore di copia in modo esplicito si dovrebbe chiamare copy c-tor di classe base in modo esplicito.

16

Credo che bisogna chiamare in modo esplicito il costruttore di copia di base:

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

Nel vostro costruttore di copia Derived, è necessario aggiungere il seguente:

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

C++ non fa alcun tipo di "abbinamento costruttore". Se non si chiama esplicitamente il costruttore della classe base, viene chiamato quello predefinito (beh, tecnicamente, la classe base subobject è "valore inizializzato", ma per le classi con costruttori questa è la stessa cosa).

1

si dovrebbe leggere this: spiega come ereditarietà & membri speciali come costruttori stanno lavorando.

0

Grazie mille. Capito. Significa che la chiamata al costruttore di copia della classe base viene eseguita automaticamente nel costruttore di copie predefinito del derivato. Mentre nel secondo caso, dal momento che sto scrivendo il costruttore di copie derivate, devo fare una chiamata esplicita al costruttore di copie della base. Grazie ancora