如果构造函数抛出异常称为析构函数? [英] Is the destructor called if the constructor throws an exception?

查看:128
本文介绍了如果构造函数抛出异常称为析构函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

寻找C#和C ++的答案。 (在C#中,与'终结'替换'析构函数')

Looking for an answer for C# and C++. (in C#, replace 'destructor' with 'finalizer')

推荐答案

preamble:香草萨特有关于这个问题的一个伟大的文章:

Preamble: Herb Sutter has a great article on the subject:

<一个href=\"http://herbsutter.word$p$pss.com/2008/07/25/constructor-exceptions-in-c-c-and-java/\">http://herbsutter.word$p$pss.com/2008/07/25/constructor-exceptions-in-c-c-and-java/

而如果它的构造函数抛出(根本不存在的对象)的对象的析构函数不会被调用,它的内部对象的析构函数可以调用。

While an object destructor won't be called if its constructor throws (the object "never existed"), the destructors of its internal objects could be called.

作为总结,对象(即,成员对象)的每个内部部分将有自己的析构函数称为在它们的结构相反的顺序进行。构造函数中内置的每一件事也没有调用析构函数,除非RAII以某种方式使用。

As a summary, every internal parts of the object (i.e. member objects) will have their destructors called in the reverse order of their construction. Every thing built inside the constructor won't have its destructor called unless RAII is used in some way.

例如:

struct Class
{
   Class() ;
   ~Class() ;

   Thing *    m_pThing ;
   Object     m_aObject ;
   Gizmo *    m_pGizmo ;
   Data       m_aData ;
}

Class::Class()
{
   this->m_pThing = new Thing() ;
   this->m_pGizmo = new Gizmo() ;
}

创建的顺序将是:

The order of creation will be:


  1. m_aObject将有人称它的构造。

  2. m_aData将有人称它的构造。

  3. 类构造函数被调用

  4. 在类的构造函数,m_pThing都会有新的,然后叫构造函数。

  5. 在类的构造函数,m_pGizmo都会有新的,然后叫构造函数。

假设我们使用以下code:

Let's say we are using the following code:

Class pClass = new Class() ;

一些可能的情况:

Some possible cases:


  • 应该m_aData扔建设,m_aObject将其析构函数调用。然后,通过新课堂分配的内存被释放。

  • Should m_aData throw at construction, m_aObject will have its destructor called. Then, the memory allocated by "new Class" is deallocated.

应该m_pThing扔新的东西(内存不足),m_aData,然后m_aObject将调用其析构函数。然后,通过新的Class分配的内存被释放。

Should m_pThing throw at new Thing (out of memory), m_aData, and then m_aObject will have their destructors called. Then, the memory allocated by new Class is deallocated.

应该m_pThing扔建设,以新的东西分配的内存将被释放。然后m_aData,然后m_aObject将调用其析构函数。然后,通过新的Class分配的内存被释放。

Should m_pThing throw at construction, the memory allocated by "new Thing" will be deallocated. Then m_aData, and then m_aObject will have their destructors called. Then, the memory allocated by new Class is deallocated.

应该m_pGizmo扔建设,由新小玩意儿分配的内存将被释放。然后m_aData,然后m_aObject将调用其析构函数。然后,通过新的Class分配的内存被释放。 注意m_pThing泄露

Should m_pGizmo throw at construction, the memory allocated by "new Gizmo" will be deallocated. Then m_aData, and then m_aObject will have their destructors called. Then, the memory allocated by new Class is deallocated. Note that m_pThing leaked

如果您要提供基本的异常保证,你一定不能漏,即使是在构造函数中。因此,你必须写这种方式(使用STL,甚至提升):

If you want to offer the Basic Exception Guarantee, you must not leak, even in the constructor. Thus, you'll have to write this this way (using STL, or even Boost):

struct Class
{
   Class() ;
   ~Class() ;

   std::auto_ptr<Thing>   m_pThing ;
   Object                 m_aObject ;
   std::auto_ptr<Gizmo>   m_pGizmo ;
   Data                   m_aData ;
}

Class::Class()
   : m_pThing(new Thing())
   , m_pGizmo(new Gizmo())
{
}

甚至

Class::Class()
{
   this->m_pThing.reset(new Thing()) ;
   this->m_pGizmo.reset(new Gizmo()) ;
}

如果你想/需要建立在构造函数中的对象。

if you want/need to create those objects inside the constructor.

这样的话,无论身在何处的构造函数抛出,什么都不会被泄露。

This way, no matter where the constructor throws, nothing will be leaked.

这篇关于如果构造函数抛出异常称为析构函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆