Folgendes kleine Programm untersucht die Semantik von Destruktoren und Konstruktoren in zusammenhang mit einem Destructor:
#include<iostream.h> class Ex { char *inst; int count; public: Ex() { cerr << "Ex()" << endl; inst="original"; count=0; } #ifdef COPYCONST Ex(const Ex& ex) { cerr << "Ex(const Ex& ex)" << endl; inst="copy"; count=0; } #endif ~Ex() { count++; cerr << "~Ex() von " << (count==1 ? inst : "plagiat" ) << endl; } }; int main() { try { throw Ex(); } #ifdef HYP1 catch(const Ex& ex) #elif HYP2 catch(Ex ex) #else catch(Ex &ex) #endif { cerr << "Ex catched " << endl; } cerr << "Ende " << endl; }Erwartet habe ich eigentlich:
Ex() Ex catched ~Ex() von original Endemit der Überlegung, daß das bei throw geworfene Objekt die Lebensdauer bis Ende des catch-Blocks haben sollte.
Bei gcc-2.95.2 und bei gcc-3.0.3 ist dies aber nicht so:
Ex() ~Ex() von original Ex catched ~Ex() von original Ende
Der Destructor wird also irgendwie zweimal aufgerufen, aber auf verschiedenen Instanzen, also wird wohl der Copy-Konstruktor aufgerufen.
Ex() Ex(const Ex& ex) ~Ex() von original Ex catched ~Ex() von copy Ende
Dieses Beweist die Vermutung.
Ex() Ex(const Ex& ex) ~Ex() von original Ex catched ~Ex() von copy Ende
Das Verhalten ändert sich nicht, wenn man verspricht, die Excpetion-Klasse nicht zu verändern.
Ex() Ex(const Ex& ex) ~Ex() von original Ex(const Ex& ex) Ex catched ~Ex() von copy ~Ex() von copy Ende
Wenn man keine Referenz bei catch angibt, wird nochmals der Copyconstruktor angegeben.