简体   繁体   中英

Throwing exception in derived class constructor. Why is base class destructor called but not derived class destructor?

#include <iostream>
class A
{
    public:
    A() 
    {   
        std::cout << "A()" << std::endl;
    }   

 virtual  ~A()
    {   
        std::cout << "~A()" << std::endl;
    }   
};

class B:public A
{
    public:
    B() 
    {   
        throw std::exception();
        std::cout << "B()" << std::endl;
    }   

   ~B()
    {   
        std::cout << "~B()" << std::endl;
    }   
};


int main()
{
    try 
    {   
        B b;
    }   
    catch(std::exception & e)  
    {   
    }   
    return 0;
}   

The above code outputs,

A()
~A()

By the time the exception is thrown, B has been created. Then why isn't the destructor of B being called?

在构造函数返回之前,该对象不被视为完全构造,并且不会在不完整的对象上调用析构函数。

Carlton is giving the right answer. This design (ie not calling dector on anything not fully constructed) has important consequence. Any C++ class can contain only one resource that is protected with destructor. For example this will not work:

class Ab
{
public:
          char *m_buff1;
          char *m_buff2;

          Ab() { m_buff1 = malloc(100); Xyz(); m_buff2 = malloc(200); }
         ~Ab() { free(m_buff1); free(m_buff2); }
};

In case if exception will happen between 2 allocation attempts - there is no way to know safely what field was initialized and what not. I give here simple example to make the point clear. Please, do not comment that it is possible to initialize the fields with NULL first. If exception will happen between mallocs - the first allocation will be simply leaked because the desctuctor will not be called.

In other words it is better to avoid designs that throw exceptions from constructors. Better think about having simple constructor that just initializes data fields and a separate method that allocates resources, opens connections, etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM