2013-03-12 13 views
5

Die Definition von some_class ist:Verhalten von explizitem Aufruf destructor

class some_class 
{ 
    // stuff 

public: 
    ~some_class() 
    { 
     delete dynamic_three; 
    } 

private: 
    classA one; 
    classB two; 
    classC* dynamic_three; 
} 

Wenn die Lebensdauer eines Objekts endet, seine Zerstörung ist: (1) seinen destructor anrufen und (2) seine Subobjekte in zerstören die gleiche Reihenfolge, in der sie in der Klassendefinition deklariert sind (= Position im Speicher).

Aber, wenn ich so etwas haben:

auto* ptr = new some_class(); 

// more stuff 

ptr->~some_class(); // l. X 

Der Schritt (2) realisiert wird, auch? Ich meine, in Zeile X werden Destruktoren von Teilobjekten auch aufgerufen oder nur der Körper des Destruktors some_class ausgeführt?

Antwort

1

Wenn die Lebensdauer eines Objekt endet, ist seine Zerstörung: (1) seinen destructor anrufen und (2) seine Subobjekte in der gleichen Reihenfolge zu zerstören, auf die sie in der Klassendefinition deklariert werden (= Position Erinnerung).

und (3) der zugewiesene Speicher wird freigegeben.

Der Schritt (2) wird auch realisiert?

Schritt (2) ja, aber nicht Schritt (3).

Aber wenn Sie

auto* ptr = new some_class(); 

Notiz schreiben, die Sie auch

std::unique_ptr<ptr> ptr (new some_class()); 

schreiben kann, die delete für Sie (natürlich nennen würde, diese nur verwenden, wenn diese Ihren Bedürfnissen entspricht, aber Nutzung Dies ist standardmäßig, wenn Sie nicht sicher sind).

+1

Ähm, nein, ein Destruktor gibt keinen reservierten Speicher frei. Der "delete" -Operator macht das. –

2

Der Schritt (2) wird auch realisiert?

Ja, es ist garantiert. Das Verhalten ist sicher, aber beachten Sie, dass Sie in Ihrem Fall keine Möglichkeit haben, den Speicher des Objekts sicher zurückzugewinnen, ohne es zuerst neu zu erstellen (es sei denn, Sie haben operator new für Ihr Objekt überlagert und Sie können so garantieren, wie der Speicher war zugeordnet und verwenden Sie die entsprechende Aufhebung der Zuordnung).

+0

Hmm. Ich wundere mich, wenn Sie Placement neu über diesen Speicher verwendet haben, wäre es sicher, dann 'delete' darauf zu nennen? Oder wäre das undefiniertes Verhalten? –

+2

@BenjaminLindley Das ist sicher ** solange der Konstruktor nicht ** werfen kann. Wenn der Konstruktor wirft, haben Sie kein Glück. –

+0

Und um ganz klar zu sein: "es neu zu konstruieren" bedeutet, es als den gleichen Typ ** neu zu konstruieren. –

2

Lassen Sie uns einen Test machen:

class classA 
{ 
public: 
    ~classA() { cout << "~classA()" << endl; } 
}; 

class classB 
{ 
public: 
    ~classB() { cout << "~classB()" << endl; } 
}; 

class some_class 
{ 
public: 
    ~some_class() { cout << "~some_class()" << endl; } 

private: 
    classA one; 
    classB two; 
}; 

int main() 
{ 
    cout << "Start..." << endl; 

    auto* ptr = new some_class(); 

    ptr->~some_class(); 

    cout << "End." << endl; 
} 

Ausgang:

starten ...

~ some_class()

~ classB()

~ classA()

Ende.

Also werden alle Destruktoren aufgerufen und in umgekehrter Reihenfolge.

Verwandte Themen