Löscht [] Aufrufdestruktoren?

8

Ich schreibe eine Template-Klasse, die intern ein Array des angegebenen Typs verwaltet. So:

%Vor%

Ich frage mich, ob C ++ den Destruktor jedes Objekts in objects aufruft, wenn ich es über delete[] objects; lösche.

Ich muss das wissen, weil die Objekte in meiner Klasse nicht immer vernünftige Werte enthalten, also sollten die Destruktoren nicht aufgerufen werden, wenn sie es nicht tun.

Außerdem würde ich gerne wissen, ob die Destruktoren aufgerufen werden, wenn ich ein Array fester Größe wie T objects[100] als Teil von Example<T> deklariere.

    
Mixthos 27.06.2013, 13:37
quelle

6 Antworten

18

Wenn T einen Destruktor hat, wird es von delete[] aufgerufen. Aus Abschnitt 5.3.5 Löschen des C ++ 11-Standards (Entwurf n3337), Abschnitt 6:

  

Wenn der Wert des Operanden des Löschausdrucks kein Nullzeigerwert ist, wird der Löschausdruck verwendet   Rufen Sie den Destruktor (falls vorhanden) für das Objekt oder die Elemente des zu löschenden Arrays auf . Im Falle eines   Array werden die Elemente in der Reihenfolge der abnehmenden Adresse (in umgekehrter Reihenfolge der Fertigstellung) zerstört   von ihrem Erbauer; siehe 12.6.2).

Der Destruktor für den Typ T wird auch für jedes Element in einem Array von T[] aufgerufen, wenn das Array nicht dynamisch zugewiesen wird und das Array den Gültigkeitsbereich verlässt (Lebensdauer endet).

  

Ich muss das wissen, weil die Objekte in meiner Klasse nicht immer vernünftige Werte enthalten, also sollten die Destruktoren nicht aufgerufen werden, wenn sie es nicht tun.

Aber es scheint ein sehr signifikantes Problem mit einem Objekt zu geben, das einen Zustand erreichen kann, in dem es nicht zerstört werden kann.

    
hmjd 27.06.2013, 13:43
quelle
3

Ja, der Destruktor wird für alle Objekte im Array aufgerufen, wenn delete[] verwendet wird. Aber das sollte kein Problem sein, da der Konstruktor für alle Objekte im Array aufgerufen wurde, wenn Sie new[] verwendet haben (richtig?), Um sie zuzuweisen.

Wenn ein konstruiertes Objekt in einem solchen Zustand sein kann, dass der Aufruf des Destruktors ungültig wäre, dann liegt etwas ernsthaft falsch an Ihrem Objekt vor. Sie müssen Ihren Destruktor in allen Fällen funktionieren lassen.

    
Sander De Dycker 27.06.2013 13:43
quelle
2

Die Antwort ist ja. Destruktor für jedes Objekt wird aufgerufen.

Bei einer verwandten Anmerkung sollten Sie versuchen, möglichst nie delete zu verwenden. Verwenden Sie stattdessen Smartpointer (z. B. unique_ptr , shared_ptr ) und STL-Container (z. B. std :: vector, std :: array).

    
segfault 27.06.2013 13:43
quelle
1

delete[] objects ist ähnlich (aber nicht identisch) mit:

%Vor%

Da delete den Destruktor aufruft, können Sie erwarten, dass delete[] dasselbe tut.

    
Nathan Fellman 27.06.2013 13:43
quelle
1

delete [] ruft den Destruktor für jedes Element des Arrays auf. Gleiches passiert für ein Mitglieder-Array (Ihr T objects[100] ).

Sie möchten es als Zeiger beibehalten und den Destruktor entwerfen (und den Konstruktor kopieren und den Zuweisungsoperator kopieren, siehe objects zeigt.

    
Nikolai Fetissov 27.06.2013 13:43
quelle
0

Ja, delete[] garantiert Destruktoren werden für jedes Objekt aufgerufen.

Abhängig von Ihrem Anwendungsfall verwenden Sie Zeigercontainer verstärken . oder einfach Container mit intelligenten Zeigern, können die Sammlung von Zeigern viel einfacher machen (Ausnahme sicher).

    
Pieter 27.06.2013 13:48
quelle

Tags und Links