2010-04-17 2 views
2

[un suivi jusqu'à this question]appels étrangers au constructeur par recopie et destructor

class A 
{ 
    public: 
     A()   {cout<<"A Construction"  <<endl;} 
     A(A const& a){cout<<"A Copy Construction"<<endl;} 
     ~A()   {cout<<"A Destruction"  <<endl;} 
}; 

int main() { 
    { 
     vector<A> t; 
     t.push_back(A()); 
     t.push_back(A()); // once more 
    } 
} 

La sortie est:

A Construction  // 1 
A Copy Construction // 1 
A Destruction   // 1 
A Construction  // 2 
A Copy Construction // 2 
A Copy Construction // WHY THIS? 
A Destruction   // 2 
A Destruction   // deleting element from t 
A Destruction   // deleting element from t 
A Destruction   // WHY THIS? 

Répondre

16

Pour voir clairement ce qui se passe, je recommande inclure le this pointeur dans la sortie pour identifier quel A appelle la méthode.

 A()   {cout<<"A (" << this << ") Construction"  <<endl;} 
    A(A const& a){cout<<"A (" << &a << "->" << this << ") Copy Construction"<<endl;} 
    ~A()   {cout<<"A (" << this << ") Destruction"  <<endl;} 

La sortie est que j'ai

A (0xbffff8cf) Construction 
A (0xbffff8cf->0x100160) Copy Construction 
A (0xbffff8cf) Destruction 
A (0xbffff8ce) Construction 
A (0x100160->0x100170) Copy Construction 
A (0xbffff8ce->0x100171) Copy Construction 
A (0x100160) Destruction 
A (0xbffff8ce) Destruction 
A (0x100170) Destruction 
A (0x100171) Destruction 

Ainsi, le flux peut être interprété comme:

  1. Le temporaire (... cf) est créé.
  2. Le caractère temporaire A (... cf) est copié dans le vecteur (... 60).
  3. Le caractère temporaire A (... cf) est détruit.
  4. Un autre A (... ce) temporaire est créé.
  5. Le vecteur est étendu, et l'ancien A (... 60) dans ce vecteur est copié dans le nouvel endroit (... 70)
  6. L'autre temporaire A (... Ce) est copié dans le vecteur (... 71).
  7. Toutes les copies inutiles de A (... 60, ... ce) sont maintenant détruites.
  8. Le vecteur est détruit, donc les A (... 70, ... 71) à l'intérieur sont également détruits.

Étape 5 sera allé si vous

vector<A> t; 
    t.reserve(2); // <-- reserve space for 2 items. 
    t.push_back(A()); 
    t.push_back(A()); 

La sortie deviendra:

A (0xbffff8cf) Construction 
A (0xbffff8cf->0x100160) Copy Construction 
A (0xbffff8cf) Destruction 
A (0xbffff8ce) Construction 
A (0xbffff8ce->0x100161) Copy Construction 
A (0xbffff8ce) Destruction 
A (0x100160) Destruction 
A (0x100161) Destruction 
+0

@KennyTM: excellente méthode et une explication! Merci! – Lazer

Questions connexes