C++ Virtual Destruktor

Tockra

Lt. Commander
Registriert
Dez. 2008
Beiträge
1.063
Hey Leute,

ich habe ein Buch über C++ gelesen, in welchem gesagt wurde, dass der Destruktor aufgrund der Vererbung virtual sein sollte. Weiteres wurde nicht wirklich erleutert.

Es wurde zwar erleutert, dass man Methoden in einer Klasse als virtual deklarieren sollte/kann, um späte Bindung bei der Polymorphie zu verwenden, allerdings kann ich das gedanklich nicht ganz auf den Destruktor übertragen...

Gruß
T
 
Verstehe ich das Beispiel richtig:

// Example 3: Obvious need for virtual destructor.
//
class Base { /*...*/ };

class Derived : public Base { /*...*/ };

Base* b = new Derived;
delete b; // Base::~Base() had better be virtual!

Hier würde der Destruktor der Base Klasse aufgerufen werden, statt dem der Derived Klasse!?
 
Tockra schrieb:
Verstehe ich das Beispiel richtig:



Hier würde der Destruktor der Base Klasse aufgerufen werden, statt dem der Derived Klasse!?

Wenn der Destruktor in Klasse Base als virtual deklariert ist, dann ist er automatisch auch in Derived virtual (innerhalb einer Vererbungshierarchy gilt einmal virtual, immer virtual), und es würde erst der Destruktor von Derived und dann der Destruktor von Base aufgerufen werden (Destruktoren werden in umgekehrter Reihenfolge der Konstruktoren aufgerufen).

Ist der Destruktor in Klasse Base __nicht__ als virtual deklariert, wird in dem Beispiel nur der Destruktor von Base aufgerufen, was natürlich ein Problem darstellt, da das gelöschte Objekt ja eigentlich eine Instanz von Derived ist.

Erwartest du also, daß in einer Klassenhierarchie Objekte polymorph gelöscht werden (also über Zeiger vom Typ einer Basisklasse), dann solltest du den Destruktor schon in der Basisklasse als virtual deklarieren, um sicherzustellen, daß die korrekten Destruktoren durchlaufen werden.
 
Zuletzt bearbeitet:
Okay, wenn wir schon beim Thema sind habe ich noch ne andere Frage.

In Java gibt es generische Interfaces, wie z.B. List<> . Kann man sowas auch in C++ bauen, sprich ein abstraktes Template, von welchem man erben kann und bei dem man denoch mit später Bindung arbeiten kann z.B. (java):
Code:
List<Integer> liste = new LinkedList<Integer>();
liste.add(5);
liste.add(12); // add ist afaik eine Methode aus dem Interface List. Hier haben wir also späte Bindung...
 
Ja, C++ hat Templates: Link
 
Tockra schrieb:
Die Frage hat doch wohl schon beinhaltet, dass ich weiß dass Templates existieren, allerdings würde nach meiner Vorstellung so ein abstraktes Template nur umsetzbar sein, wenn die Methoden eines Templates virtual sein könnten, allerdings dürfen die das afaik nicht.

Wieso soll das denn nicht gehen? Ich möchte jetzt keine Aussage über den Sinn solchen Codes in C++ treffen, aber möglich ist es allemal:

Code:
#include <iostream>
#include <memory>

template < typename T >
class List
{
public:
	virtual ~List() { std::cout << "Running List d'tor for instance at 0x" << std::hex << this << std::dec << ".\n"; }

	void add( T val )
	{
		add_impl( val );
	}

protected:
	List()
	{
		std::cout << "Running List c'tor for instance at 0x" << std::hex << this << std::dec << ".\n";
	}

private:
	virtual void add_impl( T val ) = 0;
};

template < typename T >
class LinkedList : public List< T >
{
public:
	virtual ~LinkedList() { std::cout << "Running LinkedList d'tor for instance at 0x" << std::hex << this << std::dec << ".\n"; }
	
	LinkedList()
	{
		std::cout << "Running LinkedList c'tor for instance at 0x" << std::hex << this << std::dec << ".\n";
	}

private:
	virtual void add_impl( T val )
	{
		std::cout << "Adding value " << val << " to LinkedList instance at 0x" << std::hex << this << std::dec << ".\n";

		// Hier das adden ausimplementieren ...
		// ...
	}
};

int main()
{
	std::unique_ptr< List< int > > list( new LinkedList< int > );
	list->add( 23 );
	list->add( 6 );
}
Ergänzung ()

P.S. Wieso stellt das Forum in Code-Schnipseln den Tab-Character eigentlich immer als 8 Spaces dar?? 4 Spaces wären doch wohl viel angenehmer.
 
Zuletzt bearbeitet: (LinkedList c'tor hinzugefügt ... der Vollständigkeit halber)
Zurück
Oben