Just a quick one, something you can use for your convenience. C++ does not call the destructor of an object, if its constructor threw an exception. Ok, thats clear -- and you can use that.
class MyThing {
MyThing() {
const bool success = init_something_complicated();
if(!success)
throw std::runtime_error("complicated error message");
}
~MyThing()
{
destroy_the_complicated();
}
};
Assume the code above you must not call
destroy_the_complicated() if init_the_complicated() failed. By not returning normally from the constructor the object will not be created -- therefore no destructor will be called.This is a great tool in RAII (see blog yesterday) where you have pairwise initializers and de-initializers. You can fine control when a de-initializer should be called even if its initializer did fail.
Guideline: Throw an exception in a contructor if the destructor must not be called. The object will not be created, therefore the destructor will not be called.
Guideline: Use this C++ language feature to implement RAII.
1 comment:
But: Be aware of the coming C++0x feature with delegating Constructors -- in these cases a constructor might throw, but the destructor must (and will) be called anyway.
For Example:
// C++0x !!!
struct MyClass {
int _x;
int _y;
MyClass()
: MyClass{10,20} {}
MyClass(int x)
: MyClass{x,0}
{
if(_x>100) throw /*...something*/
}
MyClass(int x, int y)
: _x(x), _y(y)
{
if(_x==_y) throw /*...something*/
}
~MyClass() { cerr << "Boom!"; }
};
The new spec says that "an object is considered constructed, if any constructor successfully finished", and therefore its destructor has to be called if something goes wrong.
In this specific case: If you construct MyClass m(999) the contruction is delegated to MyClass{999,0}. That constructor will finish successfully. This means the object is considered existent! Then the body of the original MyClass m(999) continues and will throw an exception. This means, before you notice something on the outside at the place where instanciated the object, it has to be destroyed, you will see "Boom!, and the exception will be passed to the outside.
Post a Comment