2009-12-25 6 views
1

Pour le code suivant:Deux appels à destructor

#include<iostream> 
#include<vector> 
#include<string> 
using namespace std; 

struct Test 
{ 

    string Str; 
    Test(const string s) :Str(s) 
    { 
     cout<<Str<<" Test() "<<this<<endl; 
    } 
    ~Test() 
    { 
     cout<<Str<<" ~Test() "<<this<<endl; 
    } 
}; 

struct TestWrapper 
{ 
    vector<Test> vObj; 
    TestWrapper(const string s) 
    { 
     cout<<"TestWrapper() "<<this<<endl; 
     vObj.push_back(s); 
    } 

    ~TestWrapper() 
    { 
     cout<<"~TestWrapper() "<<this<<endl; 
    } 
}; 

int main() 
{ 
    TestWrapper obj("ABC"); 
} 

Ce fut la sortie que je suis sur mon MSVC++ compilateur:

TestWrapper() 0018F854
ABC Test() 0018F634
ABC ~ test() 0018F634
~ TestWrapper() 0018F854
ABC ~ test() 003D8490

Pourquoi re sont deux appels à Test destructor bien qu'un seul objet Test soit en cours de création. Y a-t-il un objet temporaire créé entre? Si oui, pourquoi il n'y a pas d'appel à son constructeur correspondant?

Ai-je raté quelque chose?

Répondre

6

Votre sortie ne tient pas compte du constructeur de copie de test, que std::vector est susceptible d'utiliser.

L'objet de test que vous voyez est créé est la valeur temporaire transmise à push_back(), et non à vector.

2

Je pense que

vObj.push_back(s); 

implique une distribution implicite de s-Test. Alors qu'est-ce qui se passe en réalité est

vObj.push_back(Test(s)); 

et l'objet temporaire est détruit après avoir été copié dans le vecteur. L'objet dans le vecteur est construit en utilisant un constructeur de copie (pas le constructeur (const string s)) ce qui explique pourquoi vous ne voyez aucun appel de constructeur correspondant à l'appel du destructeur.

+0

Vous avez dit "et l'objet temporaire est détruit après qu'il a été copié dans le vecteur". Le dernier appel de destructeur concerne l'objet temporaire. Pourquoi n'est-il pas détruit immédiatement? –

+0

Non, le premier appel de destructeur concerne l'objet temporaire. L'objet temporaire est construit avec un argument de chaîne, ce qui explique pourquoi le constructeur est appelé. – Artelius

+0

Alors pourquoi ces deux valeurs de "this" sont-elles similaires: ABC Test() 0018F634 ABC ~ Test() 0018F634 –

2

Essayez d'ajouter un constructeur de copie à votre test:

Test(const Test &obj) 
{ 
    cout<<obj.Str<<" Test() "<<this<<endl; 
    Str = obj.Str; 
} 

Vous verrez le constructeur de copie appelé ainsi, cet appel se produit au moment où l'objet est mis dans le vecteur. Nous avons donc deux appels aux constructeurs et deux appels aux destructeurs.