Konstruktor von virtueller Klasse
-
Hallo!
Ich habe folgende Klasse:
class Klasse1 { private: Klasse2* k; public: Klasse1(); virtual ~Klasse1(); virtual void methode() = 0; }und
Klasse1::Klasse1() { k = new Klasse2(); }Natürlich habe ich noch konkrete Klassen, die von Klasse1 erben. Der GCC kompiliert das auch. Nun allokiere ich in meinem Konstruktor aber dynamisch Speicher, den ich mangels konkretem Destruktor natürlich nicht wieder los werde. Auf den virtuellen Destruktor kann ich aber natürlich auch nicht verzichten.
Mich beschleicht ja das Gefühl, dass das Konzept suboptimal ist.

Wie löst man das?
Vielen Dank.
EDIT: Beispiel korrigiert.
-
Wo ist überhaupt das Problem? Gib den Speicher im Destruktor wieder frei. Der Destruktor einer abgeleiteten Klasse ruft auch die destruktoren der basisklasse auf. Das virtual sorgt nur dafür, dass überhaupt der Destruktor der abgeleiteten Klasse aufgerufen wird.
-
Dann implementier den Destruktor halt. Du kannst eine Funktion (auch den Destruktor) dennoch virtuell machen, auch wenn er einen Funktionskörper hat.
-
Nun allokiere ich in meinem Konstruktor aber dynamisch Speicher
Nein, du allokierst im Konstruktor keinen dynamischen Speicher, sondern weist deinem Member (Pointer) einen Wert zu. Die Allokation hat bereits vor dem Konstruktor stattgefunden. Der der den Speicher da allokiert hat, ist auch fürs Zerstören verantwortlich.
, den ich mangels konkretem Destruktor natürlich nicht wieder los werde. Auf den virtuellen Destruktor kann ich aber natürlich auch nicht verzichten.
Das versteh ich nicht. Sobald ein Destruktor als virtual deklariert ist, ist er auch in abgeleiteten Klassen virtuell. Wenn du dort keinen Destruktor deklarierst, brauchst du wohl auch keinen. Wenn alle Klassen einen Destruktor implementieren, die einen brauchen, hast du eigentlich gar keine Probleme mit Memory Leaks usw...
-
Nein, du allokierst im Konstruktor keinen dynamischen Speicher, sondern weist deinem Member (Pointer) einen Wert zu. Die Allokation hat bereits vor dem Konstruktor stattgefunden. Der der den Speicher da allokiert hat, ist auch fürs Zerstören verantwortlich.
Pardon, ich wollte hier nur ein Minimalbeispiel angeben und hab dabei Mist gebaut. In meinem *eigentlichen* Konstruktor allokiere ich Speicher. Habe das oben mal editiert.
Dann implementier den Destruktor halt. Du kannst eine Funktion (auch den Destruktor) dennoch virtuell machen, auch wenn er einen Funktionskörper hat.
Gut, mehr wollte ich nicht wissen.
Vielen Dank.
-
Wenn du benutzerdefinierte Kopiersemantik brauchst, z.B. bei manueller Speicherverwaltung, dann halte dich an die Regel der Grossen Drei und implementiere zum Destruktor zusätzlich einen Kopierkonstruktor und Zuweisungsoperator. Oder – was in polymorphen Kontexten oft sinnvoll ist – verbiete diese beiden Methoden durch Deklaration ohne Definition im
private-Bereich.Aber einfach nichts tun ist keine Option, weil die vom Compiler generierten Methoden nicht das Richtige tun und unter Umständen böse mühsame Laufzeitfehler erzeugen.
-
Inbesondere wenn man solche Objekte in STL Container speichert, die darauf bauen, dass es korrekte Zuweisungsoperatoren, etc. gibt.
-
mmmm schrieb:
Inbesondere wenn man solche Objekte in STL Container speichert, die darauf bauen, dass es korrekte Zuweisungsoperatoren, etc. gibt.
AFAIK ist je nach Container der operator= oder der Copy-CTor notwendig. Kenn mich leider im Standard nicht wirklich aus, bin mir aber sicher dass das dem Implementierer der STL überlassen wird.