In my constructor, I have to destroy any remaining resources if any code in it throws. I'd like to avoid writing duplicate code so I just call the destructor in the catch block which than frees any resource that has been created. Is this safe?
I'm aware that the destructor is not called if the constructor throws, so I tried compiling some code in msvc and nothing seems wrong, but I'm not sure if this is just luck.
Object::Object(){
try{
// Initialize multiple resources here.
}catch(...){
this->~Object(); // Is this safe?
throw;
}
}
Object::~Object(){
// release multiple resources, if initialized.
}
Despite the fact that destructors look like ordinary methods, and the explicit destruction syntax looks like a call of that method, it does not actually just call that method. Among other implementation-specific things, it also calls the destructors of base classes and data members. Throwing an exception from the constructor also causes all of those destructors to be called. So, ~Object()
followed by throw
will call them twice, likely with disastrous consequences.
Just move the cleanup code to an ordinary method, as someone suggested in a comment.
There's a similar syntactic problem with the function-call syntax for constructing a temporary, and with new
/delete
and operator new
/operator delete
. None of them just call the functions with the same names, even though it looks like they should.