Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will the destructor of the base class called if an object throws an exception in the constructor?

Will the destructor of the base class be called if an object throws an exception in the constructor?

like image 628
kumar Avatar asked Sep 21 '10 10:09

kumar


People also ask

Will the destructor be called if the constructor throws exception?

When an exception is thrown from a constructor, the object is not considered instantiated, and therefore its destructor will not be called. But all destructors of already successfully constructed base and member objects of the same master object will be called.

Is destructor called when exception is thrown?

Yes, destructors are guaranteed to be called on stack unwinding, including unwinding due to exception being thrown. There are only few tricks with exceptions that you have to remember: Destructor of the class is not called if exception is thrown in its constructor.

What happens when a destructor throws exception?

Throwing an exception out of a destructor is dangerous. If another exception is already propagating the application will terminate. This basically boils down to: Anything dangerous (i.e. that could throw an exception) should be done via public methods (not necessarily directly).

Is the base class destructor automatically called?

No, destructors are called automatically in the reverse order of construction. (Base classes last). Do not call base class destructors.


2 Answers

Yes. The rule is that every object whose constructor has finished successfully will be destructed upon exception. E.g:

class A {
public:
    ~A() {}
};

class B : public A {
public:
    B() { throw 0; }
    ~B() {}
};

~A() is called. ~B() is not called;

EDIT: moreover, suppose you have members:

struct A {
    A(bool t) { if(t) throw 0; }
    ~A() {}
};

struct B {
    A x, y, z;
    B() : x(false), y(true), z(false) {}
};

What happens is: x is constructed, y throws, x is destructed (but neither y nor z).

like image 33
Yakov Galka Avatar answered Sep 20 '22 03:09

Yakov Galka


If an exception is thrown during construction, all previously constructed sub-objects will be properly destroyed. The following program proves that the base is definitely destroyed:

struct Base
{
    ~Base()
    {
        std::cout << "destroying base\n";
    }
};

struct Derived : Base
{
    Derived()
    {
        std::cout << "throwing in derived constructor\n";
        throw "ooops...";
    }
};

int main()
{
    try
    {
        Derived x;
    }
    catch (...)
    {
        throw;
    }
}

output:

throwing in derived constructor
destroying base

(Note that the destructor of a native pointer does nothing, that's why we prefer RAII over raw pointers.)

like image 129
fredoverflow Avatar answered Sep 20 '22 03:09

fredoverflow