C++
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.