【问题标题】:How the try / catch in initialization list works?初始化列表中的 try / catch 是如何工作的?
【发布时间】:2012-09-23 17:44:55
【问题描述】:

我们认为可能会发生初始化异常。所以我们写了 try/catch 块。

int f(){
    throw 1;
}

class A
{
public:
    A() try : _k(f())
    {}
    catch (int)
    {
        std::cout << "Exception 1" << std::endl;
    }

private:
    int _k;
};

但是 catch 会在更深一层上重新抛出异常。这意味着下一个代码

try
{
    A a;
} catch(int)
{
    std::cout << "Exception 2" << std::endl;
}

将输出:

Exception 1
Exception 2

为什么这个 try / catch 块的行为方式与普通的 try / catch 块不同?

完整代码示例:http://ideone.com/XjY2d

【问题讨论】:

    标签: c++ exception exception-handling try-catch in-class-initialization


    【解决方案1】:

    因为它不是普通的 try-catch 块,而是函数级的 try/catch。除非您使用 throw 明确执行此操作,否则它会自动重新抛出。

    【讨论】:

    • 我知道这不是普通的块。但我想知道它是如何决定以这种方式工作的。
    • 那么您可能会澄清问题中的粗体文本。正如其他人指出的那样,主要思想是考虑到调用者,对象无法构造。在构造过程中通知错误的唯一方法是通过异常。
    【解决方案2】:

    您的问题似乎是:为什么函数级别的 try/catch 会自动重新抛出异常?从对象的构造中抛出异常,这个对象在它复活之前就被认为是死的。它的所有子对象都被销毁。也就是说,如果在构造过程中抛出异常,则没有对象。如果异常不会抛出,您将得到一个对象的外壳。这显然是不可取的。

    【讨论】:

    • 注意:只有当你不扔掉自己退出catch块时,它才会自动重新抛出。
    【解决方案3】:

    您正在构造的对象尚未真正构造,因此简单的返回不是一种选择。这种 try0-catch 总是重新抛出(除非你从 catch 子句中抛出你自己的异常)。

    【讨论】:

      猜你喜欢
      • 2013-11-14
      • 2012-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-12
      • 1970-01-01
      • 2020-08-22
      • 2014-12-13
      相关资源
      最近更新 更多