2015-04-24 5 views
11

Eigentlich denke ich über trivial zerstörbare Objekte, nicht nur über POD (ich bin nicht sicher, POD kann Basisklasse haben).Ist es sicher, ein POD-Objekt durch einen Zeiger auf seine Basis zu löschen?

Wenn ich lese diese Erklärung für is_trivially_destructible von cppreference Ich bemerke dies:

Lagerung von trivialer zerstörbare Objekte besetzt werden können, ohne den Aufruf der destructor wiederverwendet werden.

So ist es sicher, das zu tun:

struct A { 
    int a; 
}; 
struct B : A { 
    int b; 
}; 
int main() { 
    A* a = new B; 
    delete a; 
} 

B::~B() wird nicht genannt werden - und AFAIK (bitte korrigieren, wenn ich falsch bin) der gesamte Speicher freigegeben wird. Und B::~B() ist sicher trivial.

Ich weiß, dass dieser Code schlecht riecht, aber meine Frage ist nur über Sicherheit dieses Codes ...

+0

Sind Sie sicher, dass 'a' immer auf eine' B' -Instanz zeigt und dass 'B' trivial zerstörbar bleibt? Wenn jemand "B" ändert oder es durch eine nicht-trivial zerstörbare Unterklasse von "B" ersetzt, wird er automatisch einen Fehler einführen. – Kos

+0

Ich verstehe nicht ganz den Punkt, den Sie anstreben. Wenn Sie ein Heap-allokiertes Objekt wiederverwenden wollten, würden Sie den Heap-Speicher nicht freigeben (zusammen mit dem Löschaufruf), aber Sie würden die unbenutzte Instanz in einer Art Recyclingcontainer behalten, anstatt dafür delete aufzurufen. Sie hätten wahrscheinlich auch eine "Factory" -Methode, um eine Instanz zu erhalten, die zuerst versuchen würde, alte Instanzen zu recyceln, bevor neue Instanzen mit neuen erstellt werden. – BitTickler

+0

Scratch mein vorheriger Beitrag lol. Er fragte, ob er einen virtuellen Destruktor braucht, ohne diese Worte zu benutzen :) – BitTickler

Antwort

18

Nein, das ist nicht erlaubt. [Expr.delete]/p3, emphasis Mine:

In der ersten Alternative (Objekt löscht), wenn der statische Typ des Objekts von seinem dynamischen Typ, der statische Typ verschiedenen gelöscht werden ist eine Basisklasse des dynamischen Typs des Objekts seiner gelöscht werden und der statische Typ einen virtuellen destructor oder das Verhalten nicht definiert ist haben soll.

In der Tat, das Komitee vor kurzem rejecteda proposal to make deleting a POD via a pointer-to-base well-defined.

+2

Vielleicht ist erwähnenswert, ob das explizite Aufrufen von ':: operator delete (a)' eine gültige Problemumgehung ist. Soweit ich sehen kann, wäre das gültig. Ich würde es jedoch nicht empfehlen, wenn es eine Möglichkeit gibt, dass "delete a;" tatsächlich einen anderen 'operator delete' aufgerufen hätte. – hvd

Verwandte Themen