开发者

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 constr开发者_StackOverflowuctor?


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.)


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).


From Standard docs, 15.3 - 11,

The fully constructed base classes and members of an object shall be destroyed before entering the handler of a function try- block of a constructor or destructor for that object.


When an exception is thrown, the destructors are called for all (sub-) objects whose constructors were successfully run. This extends to data members and base classes alike.

For example, for this code

struct base {};

struct good {};

struct bad {
  bad() {throw "frxgl!";}
};

struct test : public base {
  std::string s;
  good g;
  bad b;
  test() {}
};

before test's constructor is executed, first the constructor for the base class is called, then the constructors for s, g, and b. Only if these finish successfully, the constructor for test is executed. When the exception is thrown during the construction of b, the base class constructors as well as the constructors for the data members s and g have been fully executed, so their destructors are run. The constructor of test itself and of b have not been run successfully, so their destructors are not run.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜