【问题标题】:Exception within function returning value for constructor构造函数返回值中的异常
【发布时间】:2010-07-25 14:53:35
【问题描述】:

假设我有一个充当“智能指针”并在销毁时释放某种系统资源的类。

class Resource{
protected:
     ResourceHandle h;
public:
     Resource(ResourceHandle handle)
     :h(handle){
     }

     ~Resource(){
         if (h)
             releaseResourceHandle(h);//external function, probably from OS
     }
};

我有一些函数可以返回用于初始化“资源”的值:

ResourceHandle allocateHandle();

现在,如果我在我的代码中这样做:

Resource resource(allocateHandle());

AND allocateHandle() 抛出异常,究竟会发生什么?崩溃会发生在 Resource() 构造期间还是构造之前?

常识告诉我,因为在 allocateHandle 返回之前抛出异常,执行甚至不会进入 Resource() 构造函数,但我不确定。这是一个正确的假设吗?

【问题讨论】:

    标签: c++ exception constructor smart-pointers raii


    【解决方案1】:

    参数在任何函数调用之前进行评估——在这种情况下是构造函数——。 因此,在构造函数调用之前抛出异常

    【讨论】:

      【解决方案2】:

      是的,你是对的(正如其他人所说的那样)。

      但是你在暗示什么(我认为)。
      如果进入构造函数并抛出异常,对象会发生什么。

      析构函数是否仍会被执行?

      只有在构造函数实际完成时才会触发析构函数(如果抛出异常而使构造函数转义,则构造函数未完成)。在这种情况下,构造函数没有进入,因此对象不存在,因此析构函数不会被执行。

      如果在构造函数执行时抛出异常会发生什么。
      在这种情况下,因为构造函数没有完成,析构函数也永远不会被执行,但是所有成员字段呢?如果构造函数通过异常离开,则所有完全形成的成员都将调用其析构函数(完全形成的成员是其构造函数已被调用并成功完成的成员)。

      【讨论】:

        【解决方案3】:

        这是一个正确的假设。

        【讨论】:

          【解决方案4】:

          如果编译器进入构造函数,它可以从一个没有返回的函数中传入什么值?

          【讨论】:

            【解决方案5】:

            是的,你的假设是正确的。

            此时您只是创建参数并将它们压入堆栈。 “资源”的对象甚至都没有形成!

            因此,异常不会在堆栈展开期间调用析构函数。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2012-08-07
              • 2016-10-21
              • 2019-04-09
              • 2011-10-14
              • 2023-04-07
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多