pure virtual Memberfunktion -> Compilerfehler - pure virtual Destructor -> Linkerfehler
-
Mis2com schrieb:
Weil ein Standard-dtor erstellt wird?
glaube ich kaum
außerdem heißt es:
virtual ~Base() = 0 { }
-
Shlo schrieb:
virtual ~Base() = 0 { }
wäre es denn dann noch eine rein virtuelle Methode mit den {} Schaut irgendwie wiedersprüchlich aus.
-
Shlo schrieb:
Mis2com schrieb:
Weil ein Standard-dtor erstellt wird?
glaube ich kaum
außerdem heißt es:
virtual ~Base() = 0 { }
lässt sich nicht kompilieren.
-
Ist nicht ganz so widersprüchlich wie es scheint, aber syntaktisch falsch. Der Dtor muss dann ausserhalb der Klasse implementiert werden.
-
das {} hat dann nur den Zweck, dass die Basisklasse eine Implementation für die rein-virtuelle Methode hat.
Diese wird aber implizit niemals verwendet, Folgendes geht aber:#include <iostream> using namespace std; class Base { public: virtual void use() = 0 {cout << "test";} }; class Derived : public Base { public: virtual void use() {Base::use();} };
Allerdings gibt es bei rein-virtuellen Funktionsimplementationen auch keine andere Möglichkeit dieses Aufrufs und die Funktion muss nach wie vor überladen werden.
MfG Eisflamme
-
Ah man lernt nich aus
Und wie is das mit dem Linker wenn =0; steht und ein std dtor erstellt wird ?
-
Warum kommt bei einer pure virtual Memberfunktion die man in einer abgeleiteten Klasse nicht implementiert ein Compilerfehler und bei einem pure virtual Destruktor den man in einer abgeleiteten Klasse nicht implementiert ein Linkerfehler?
Es kommt zu einem Compilerfehler, wenn du versuchst eine Klasse zu instanziieren, die eine rein virtuelle Funktion hast, da eine solche Klasse als abstrakt und damit nicht instanziierbar definiert ist.
Besitzt deine Basisklasse einen rein virtuellen Destruktor ohne Implementation und überschreibst du nun in einer abgeleiteten Klasse alle rein virtuellen Funktionen, dann kommt es zu zu einem Linkerfehler, wenn du eine Instanz der abgeleiteten Klasse erzeugst, weil der Compiler in einem Dtor automatisch Code einfügt, der den Dtor der Basisklassen aufruft. Auch wenn diese Basisklasse rein virtuelle Funktionen enthält und damit abstrakt ist.
In deinem konkreten Fall:
Dein Objekt d ist ein automatisches Objekt. Am Ende von main wird es zerstört. Dabei wird der Destruktor von Derived aufgerufen. Dieser ruft automatisch den Destruktor von Base auf. Da dieser aber nicht definiert ist, kommt es zum Linkerfehler.Weil ein Standard-dtor erstellt wird?
Der dient als final-overrider. Stellt aber natürlich keine Implementation für den *Basis*klassendtor bereit.
Shlo schrieb:
Mis2com schrieb:
Weil ein Standard-dtor erstellt wird?
glaube ich kaum
außerdem heißt es:
virtual ~Base() = 0 { }
Nein heißt es nicht. Das ist kein legales C++. Du musst die Deklaration des rein virtuellen Dtors von seiner Implementation trennen:
// Im header class A { public: virtual ~A() = 0; }; // Am Besten in einer cpp A::~A() {}
-
Bashar schrieb:
Ist nicht ganz so widersprüchlich wie es scheint, aber syntaktisch falsch. Der Dtor muss dann ausserhalb der Klasse implementiert werden.
Und was bringt das? Ist das dann nicht das Gleiche als wie man den Destruktor nur virtual (nicht pure virtual) macht? Oder was ändert sich dadurch?
-
Mis2com schrieb:
Allerdings gibt es bei rein-virtuellen Funktionsimplementationen auch keine andere Möglichkeit dieses Aufrufs und die Funktion muss nach wie vor überladen werden.
Überschrieben, nicht überladen.
Ist das dann nicht das Gleiche als wie man den Destruktor nur virtual (nicht pure virtual) macht?
Nö. Ein rein virtueller Destruktor macht eine Klasse abstrakt, so wie jede andere reine virtuelle Methode auch.
-
Ist das dann nicht das Gleiche als wie man den Destruktor nur virtual (nicht pure virtual) macht?
Nö. Ein rein virtueller Destruktor macht eine Klasse abstrakt, so wie jede andere reine virtuelle Methode auch.[/quote]
Reicht denn *eine* rein virtuelle Memberfunktion um eine Klasse abstrakt zu machen?
Ich meine, wenn man jetzt schon eine rein virtuelle Memberfunktion hat, ändert sich dann noch etwas durch Hinzufügen eines *rein* virtuellen Destruktors?
-
Rocky! schrieb:
Reicht denn *eine* rein virtuelle Memberfunktion um eine Klasse abstrakt zu machen?
Jup.
Ich meine, wenn man jetzt schon eine rein virtuelle Memberfunktion hat, ändert sich dann noch etwas durch Hinzufügen eines *rein* virtuellen Destruktors?
An der abstraktheit der Klasse nicht, nein.
Hier tut es dann auch ein normaler virtueller Destruktor. Der verwirrt C++ Anfänger auch nicht so sehr. Ein rein virtueller Destruktor ist halt nützlich, wenn man eine abstrakte Klasse haben will, aber ansonsten keinen guten Kandidaten für eine rein virtuelle Methode hat oder aber als Lehrbeispiel für eine rein virtuelle Methode, die *immer* eine Implementation benötigt.
Gehört ins Kapitel "rein virtuelle Methoden != Methoden ohne Implementation. Beispiel: Der rein virtuelle Destruktor" in jedes C++ Einsteigerbuch.
-
kann mir jemand erklären, warum
virtual ~Brick(){};
eine undefined reference produziert, dagegen aber das hier problemlos läuft:
virtual ~Brick(); // // // Brick::~Brick() { }
-
das ";" ist falsch