2010-07-14 11 views
24

Gibt es einen Unterschied zwischen einem geschützten und einem privaten Destruktor in C++? Wenn ein Basisklassen-Destruktor privat ist, stelle ich mir vor, dass er immer noch aufgerufen wird, wenn das abgeleitete Klassenobjekt gelöscht wird.Protected vs Private Destructor

+4

Sie haben einige Probleme von der Klasse mit privaten Destruktor =) – SadSido

+0

Duplizieren für http://stackoverflow.com/questions/631783/what-is-the-use-of-having-destructor-as-private ? – SadSido

+1

Ähnliche Fragen hier: http://stackoverflow.com/questions/224966/private-and-protected-members-c – Jordan

Antwort

12

Entnommen here:

Wenn der Konstruktor/Destruktor als privat deklariert wird, dann kann die Klasse nicht instanziert werden.

Dies ist richtig, jedoch kann es von einer anderen Methode in der Klasse instanziiert werden. Wenn der Destruktor private ist, kann das Objekt auch nur innerhalb der Klasse gelöscht werden. Außerdem verhindert es, dass die Klasse vererbt wird (oder zumindest verhindert, dass die geerbte Klasse überhaupt instanziiert/zerstört wird).

+4

öffentliche Klasse A {private A() {} public A getA() {return new A(); }} Nicht genau richtig. –

+2

Das stimmt nicht. Objekt mit privatem Destruktor * kann * instanziiert werden (z. B. auf einem Stapel innerhalb einer Friend-Funktion). – SadSido

+2

Right kann nicht Stack zugewiesen werden, aber kann Heap zugewiesen werden und auch von Freunden Funktionen ... –

22

Wenn der Basisklasse-Destruktor private oder protected ist, können Sie delete nicht über den Basisklassenzeiger aufrufen.

Verwenden Sie einen geschützten Destruktor, um die Zerstörung eines abgeleiteten Objekts durch einen Basisklassenzeiger zu verhindern. Es beschränkt den Zugriff auf den destuctor auf abgeleitete Klassen. Und es verhindert automatische (Stapel) Objekte der Klassenbasis.

In der Tat ist es zu ermöglichen, jede andere polymorphe Verwendung von abgeleiteten Klassen über Zeiger auf Basis verwendet, aber nicht erlauben den Benutzern die Verwendung eines solchen Zeiger zu löschen. Beispiel: - Abstrakte Basisklassen/Schnittstellen.

Aber ein protected scheint non-virtual destructor um einen Fehler zu warten geschehen. Angenommen, Sie stellen keine destroy() Funktion zur Verfügung, müssen Sie das dtor schließlich öffentlich machen. Sobald Sie das tun, haben Sie keine weitere Kontrolle über die Klasse und riskieren polymorphes Löschen mit einem nicht virtuellen dtor, wenn sich jemand weiter von Ihrer Klasse ableitet.

6

Das folgende Stück Code wird in den Compiler-Fehlern führen (VC2010): C2248: 'base :: ~ base': kann nicht privat Mitglied in der Klasse 'Basis' erklärte Zugriff

class base 
{ 
    ~base(){} 
}; 

class derived : public base 
{ 
}; 

int main() 
{ 
    derived* d = new derived; 

    delete d; 
} 

Wenn jedoch Sie ändern den Basisdestruktor, um geschützt zu werden, alles funktioniert gut.

+0

Aber selbst wenn Sie es in 'protected' geändert haben, konnten Sie Objekte nicht durch einen Basisklassenzeiger zerstören. (In diesem Fall sollte es auch "virtual" sein, BTW.) Was einige der Zwecke der Ableitung etwas besiegt ... – sbi

6

Die Antwort ist, dass Ihre Annahme falsch ist. Der Basisklassendestruktor kann nicht aufgerufen werden, wenn er privat ist.

+0

Also wie wird meine Klasse zerstört? – doron

+0

@ deus-ex-machina399: Es kann nicht. Daher können Sie daraus nicht ableiten. Und Sie können keine automatischen Objekte davon erstellen. Und dynamische Objekte können nie gelöscht werden (es sei denn, Sie stellen eine Memberfunktion zur Verfügung, die dies tut). – sbi