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

前端 未结 4 759
失恋的感觉
失恋的感觉 2021-01-07 23:08

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

相关标签:
4条回答
  • 2021-01-07 23:45

    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.

    0 讨论(0)
  • 2021-01-07 23:54

    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 讨论(0)
  • 2021-01-08 00:04

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

    0 讨论(0)
  • 2021-01-08 00:06

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

    0 讨论(0)
提交回复
热议问题