2013-01-16 9 views
6

Etwas trat in meinem Programm, und ich kann nicht finden, wenn es geschehen ist oder nicht angenommen hat. Und wenn es ist, sehe ich nicht, warum ..Warum wird der Destruktor beim Initialisieren und Ändern der Größe eines Objektvektors aufgerufen?

Hier ist der Code:

#include <iostream> 
#include <vector> 

using namespace std; 

class A{ 
    public: 
    A(); 
    ~A(); 
}; 

A::A(){ 
    cout << "creating" << endl; 
} 

A::~A(){ 
    cout << "deleting" << endl; 
} 

int main(void){ 
    vector<vector<A > > vec; 

    vec.resize(5); 
    for(int i = 0; i < 5; ++i){ 
    vec[i].resize(5); 
    } 

    cout << "END" << endl; 

    return 0; 
} 

Und hier ist der Ausgang:

creating 
deleting 
creating 
deleting 
creating 
deleting 
creating 
deleting 
creating 
deleting 
END 
deleting 
deleting 
[..more deleting here] 

Ich verstehe, warum der destructor nach dem genannten " ENDE "Nachricht, aber vorher, ich nicht. Ich dachte, dass wenn der Vektor die Größe ändert, der Konstruktor der Klasse aufgerufen wird, aber warum der Destruktor?

+0

Sie haben vergessen, die Ctor Kopie vom Benutzer definiert werden. Wenn Sie (mit Ausgabe) und nach jedem Aufruf eine Ausgabe auf resize() setzen, werden Sie sehen, was passiert. –

Antwort

17

In C++ 03 vector<A>::resize() hat einen Standardparameter mit Standardwert A(). Es ist dieses temporäre, das zerstört ist. Die Elemente der Vektoren sind Kopien davon konstruiert.

Dies wird als "feste" in C++ 11, wo es zwei Überlastungen von resize. Einer hat einen einzigen Parameter und value-initialisiert alle zusätzlichen Elemente. Der andere hat zwei Parameter und initialisiert jedes zusätzliche Element aus dem angegebenen Wert. In C++ 11 dieses Programm dieses Verhalten hat:

creating 
creating 
creating 
<repeated for a total of 25 "creating"s> 
creating 
creating 
creating 
END 
deleting 
deleting 
deleting 
<repeated for a total of 25 "deleting"s> 
deleting 
deleting 
deleting 

in C++ 03, wenn eine Instanz von A so erschreckend teuer zu konstruieren, dass sie die Zahl wert minimiert, dann könnte man es aus 5 nicht rasieren -args- + 25 copy-Konstruktionen bis zu 1 no-Arg- und 25 copy-Konstruktionen mit etwas wie folgt aus:

A default_value; 
for (int i = 0; i < 5; ++i) { 
    // same end result as vec[i].resize(5) 
    if (vec[i].size() >= 5) { 
     vec[i].erase(vec.begin() + 5, vec.end()); 
    } else while(vec[i].size() < 5) { 
     vec[i].push_back(default_value); 
    } 
} 

Sie können es wahrscheinlich schreiben etwas anders, und natürlich für Ihren Beispielcode nicht wahr brauche den "if" -Fall. Aber ich bekomme nicht viele Gelegenheiten, "else while" zu sagen, also nehme ich es.

+0

Es ist erwähnenswert, dass sich dieser Code in C++ 11 völlig anders verhält. – Csq

+0

@Csq: Ja, ich bin weit vor dir. Für Werte von "Weg" gleich "kaum". Ich habe gerade den Standard überprüft, bevor ich das Bit gepostet habe :-) –

+0

Okay ... also gibt es keine Möglichkeit, es ohne C++ 11 zu reparieren? Danke :) – user1729422

Verwandte Themen