005
04.02.2004, 16:55 Uhr
virtual
Sexiest Bit alive (Operator)
|
Zitat: |
0xdeadbeef postete Exception geschmissen wird...au weia... virtual?
|
Ja? Ich sehe kein Problem: Wird im ctor ne Exception geworfen, wird alle bisher konstruierte wieder freiegegeben, dh insbes. alle Basisklasse werden wieder abgeräumt. Natürlich muß man ein wenig aufpassen:
C++: |
class NaiveClass: public BasicClass { NaiveClass() :BasicClass { char* x = new char[100]; char* y = new char[1000000000]; ... delete[]y; delete[]x; } };
|
Es gibt eine gute Wahrscheinlichkeit, daß das new für y schief geht. Ohne vorkehrungen hat man ein Speicherloch, weil x nicht freigeben wird. Dies ist allerdings eine Angelegenheit, die unabh. von ctor zu beachten ist (dh das gleiche kann auch in eienr normalen methode passieren).
Problematisch sind lediglich Exceptions, die aus Destructoren heraus geworfen werden: diese sollten (um jeden Preis) verhindert werden:
C++: |
class BadClass { public: virtual ~BadClass() { throw "I'm just bad"; } };
... void f() { try { BadClass bad1; ... throw "I am a normal String thrown f"; } // Problematische Stelle! catch(...) { } }
|
Die Problematische Stelle ist mit einem Kommentar versehen: In der Zeile darüber wird eine Exception geworfen, dh der try Block wird verlassen und alle lokalen Variablen dieses Blocks werden freigeben. Dies bedeutet, daß der dtor von BadClass implizit aufgerufen wird, so daß man plötzlich - während die erste Exception noch nicht gefangen ist - eine zweite am Hals hat. Dies wird von C++ mit einem Aufruf von std::unexpected() quitiert, was wiederum (solange man nichts anderes sagt zu einem std::terminate() führt (der Name ist programm: Das Programm terminiert!)). Ganz davon abgesehen bewirkt eine Exception im dtor, daß ein Object ggf. nicht komplett abgeräumt wird und so ein Speicherloch produiert. Fürde etwas im Bsp ganz oben der dtor von NaiveClass eine Exception werfen, würde nicht mehr der dtor von BasicClass erreicht.
Mit std::uncaught_exception() kann übrigens herausfinden, ob man grade in der Situation ist, daß die lokalen Variablen abgeräumt werden, um im catch Block zu landen:
C++: |
class BadClass { public: virtual ~BadClass() { if(std::uncaught_exception()) std::cerr <<" Gleich gehts in the catch block, weil was dummes passiert ist!"<<std::endl; } };
... void f() { try { BadClass bad1; ... throw "I am a normal String thrown f"; } // Gibt obigen text aus! catch(...) { } try { BadClass bad1; ... } // Gibt obigen text nicht aus, wiel keine exception geworfen wurde! catch(...) { } }
|
Bearbeitung: |
Sorry für die Rechtschreibfehler. Ich bin aber zu müde, sie alle rauszuholen
|
-- Gruß, virtual Quote of the Month Ich eß' nur was ein Gesicht hat (Creme 21) Dieser Post wurde am 04.02.2004 um 16:57 Uhr von virtual editiert. |