====== Virtuelle Destruktoren ====== Wenn eine Klasse virtuelle Methoden enthält, sollte sie zusätzlich auch den Destruktor virtuell beschreiben. Nehmen wir folgendes Szenario an: #include #include class Node { public: Node * Next; Node * Prev; char * UserData; Node() : Next( NULL ) , Prev( NULL ) { UserData = new char[500]; } ~Node() { printf( "Destruiere Node - loesche UserData\n" ); delete [] UserData; } }; class MyNode : public Node { public: char * MoreData; MyNode() { MoreData = new char[500]; } ~MyNode() { printf( "Destruiere MyNode - loesche MoreData\n" ); delete [] MoreData; } }; void deleteNode( Node * toDelete ) { delete toDelete; } int main( void ) { MyNode *myNode1, *myNode2; myNode1 = new MyNode; myNode2 = new MyNode; deleteNode( myNode1 ); delete( myNode2 ); return EXIT_SUCCESS; } Dieses Programm ist nicht objektorientiert, die Funktion ''deleteNode'' erhält einen Pointer auf ''Node'' und gibt diesen frei. Da der Destruktor nicht virtuell ist, also nicht Objekttyp-Abhängig ist, ruft C++ den Destruktor entsprechend des Datentypes von ''toDelete'' - und das ist Node, nicht MyNode. Schauen wir uns die Ausgaben an: Destruiere Node - loesche UserData Destruiere MyNode - loesche MoreData Destruiere Node - loesche UserData Obwohl die Funktion deleteNode einen Zeiger auf ein Objekt der Klasse ''MyNode'' erhält, geht Information, dass es sich um ein MyNode handelt verloren und C++ sieht in ''deleteNode'' nur noch den Zeiger auf ein ''Node'' und ruft den Konstruktor, der für ''Node'' gilt. Da der Destruktor nicht virtual ist, wird Node::~Node() gerufen. Dies ist aber ja nicht gewünscht, zuerst muss ja der Destruktor MyNode::~MyNode gerufen werden, damit auch der Member ''MoreData'' freigegeben wird und dieser Destruktor anschließend den Destruktor seiner Basisklasse ruft. Um das einzurichten, erklären wir den Destruktor von ''Node'' für virtual: virtual ~Node() { printf( "Destruiere Node - loesche UserData\n" ); delete [] UserData; } Nun weiß delete, dass es den Destruktor in der virtual Table suchen muss und findet dort den Destruktor von ''~MyNode''. Somit erhalten wir das richtige Ergebnis: Destruiere MyNode - loesche MoreData Destruiere Node - loesche UserData Destruiere MyNode - loesche MoreData Destruiere Node - loesche UserData