2012-03-29 4 views
2

Wenn wir keine virtuellen Konstruktoren haben, warum haben wir dann virtuelle Destruktoren? Können Konstrukteure auch virtuell sein?Nein Virtuelle Konstruktoren aber virtueller Destruktor

+0

möglich Duplikat von [Warum haben wir keinen virtuellen Konstruktor in C++?] (Http://stackoverflow.com/questions/733360/why-do-we-not-have-a-virtual-constructor-in- c) –

+1

@TomaszNurkiewicz: Ich denke, die Frage ist eher, warum haben wir virtuelle Destruktoren in C++? –

Antwort

16
  • Es gibt keinen Punkt in der virtuellen Konstruktor - Sie erklären genau, was Typ erstellt wird, und es ist gut in der Kompilierung bekannt. Der Compiler benötigt [und kann eigentlich nicht, da der dynamische Versand basiert auf Informationen, die erst erstellt wird, nachdem das Objekt erstellt wurde]. So gibt es keine virtuellen Konstruktoren.
  • Virtuelle Destruktoren sind wichtig, um Speicherlecks zu vermeiden, und überwachen das System. Angenommen, Sie haben A* a = new B; [B erben von A] und später delete a; - der Compiler hat keine Möglichkeit, a zu wissen, ist ein B [im allgemeinen Fall] und wird A ‚s destructor aufrufen - wenn es nicht ist virtuell, und Sie könnten ein Speicherleck, oder andere Fehler erhalten.
  • Mit virtuellen destructor - Sie sicherzustellen, dass B ‚s destructor ist aufgerufen, da ein B Objekt zerstört.
+0

Ich habe den ersten Punkt nicht verstanden. Kannst du es bitte ausarbeiten? – devsda

+1

@jhamb: Wenn Sie einen Konstruktor aufrufen - es ist so etwas wie 'new MyClass;'. Der * dynamische Typ * und der * statische Typ * des erstellten Objekts sind genau dieselben, das reale konkrete Objekt. – amit

2

Virtuelle Destruktoren werden, weil bei Zerstörung Zeit benötigt, Sie wissen nicht immer, welche Art mit Ihnen zu tun hat:

Base *make_me_an_object() 
{ 
    if (the_moon_is_full()) 
     return new Derived(); 
    else 
     return new Base(); 
} 

int main() 
{ 
    Base *p = make_me_an_object(); 
    delete p; 
} 

Die delete in dem main der obigen Programm weiß nicht, ob seine p verweist auf ein Base oder einem Derived Objekt, aber wenn der Base destructor virtual ist (wie es sein soll), kann dann delete*p ‚s verwenden vtable das Recht destructor zu finden.

Im Gegensatz dazu wissen Sie zur Konstruktionszeit immer, welche Art von Objekt Sie erstellen. (Und falls Sie nicht, dann können Sie eine Fabrik oder „virtual constructor“ erstellen, der kennt.)

0
#include<iostream> 
using namespace std; 
class base { 
    protected: 
    int a; 
}; 
class derived : public base { 

}; 
int main() { 
    base * pointer_of_base = new derived; 
    delete pointer_of_base; // this will delete the base calss not the derived 

} 

Die Konstrukteure auf einmal aufgerufen werden, wenn wir das Objekt der Klasse erstellen, damit, wenn wir erben Die Konstruktoren der Basisklasse rufen nur ein einziges Mal auf, sodass sie nicht virtuell sein müssen.

Wenn wir jedoch vom Zeiger der Basisklasse auf die abgeleitete Klasse zugreifen, löschen wir das Objekt der abgeleiteten Klasse durch den Zeiger der Basisklasse, aber delete (pointer_of_base) wird den Destruktor der Basis aufrufen Klasse, aber das eigentliche Motto ist, die abgeleitete Klasse zu löschen. also müssen wir den Destruktor virtuell in der Natur haben.