C++ Try-catch语法构造函数

C++ Try-catch语法构造函数,c++,exception,C++,Exception,我只是想问问自己,为什么我不应该简单地避开构造函数的try/catch语法,然后写下: struct base { base() { throw std::exception(); } }; struct derived : public base { derived() : base() { } }; int main() { // This works fine. try { derived a; } catch(std::e

我只是想问问自己,为什么我不应该简单地避开构造函数的try/catch语法,然后写下:

struct base
{
    base() { throw std::exception(); }
};

struct derived : public base
{
    derived() : base() { }
};

int main()
{
    // This works fine.
    try {
       derived a;
    }
    catch(std::exception& e)
    {
      std::cout << "exception handled" << std::endl;
    }
    return 0;
}
struct base
{
base(){throw std::exception();}
};
结构派生:公共基
{
派生():基(){}
};
int main()
{
//这个很好用。
试一试{
导出了一个;
}
捕获(标准::异常&e)
{

std::cout将try/catch包装在超类的构造函数中,可以捕获在超类的构造函数中抛出的异常;但是,当
catch
块结束时,异常会自动重新抛出,并且异常会继续传播

毕竟,超类没有被构造。它抛出了一个异常。因此,你不能真的继续你的快乐方式,在子类的构造函数中,然后以一个构造的子类结束,但是以一个没有被构造的超类结束。这没有意义

发件人:

函数try块的主要用途是记录或修改,以及 然后在中重新显示从成员初始值设定项列表中抛出的异常 构造函数。它们很少与析构函数或正则表达式一起使用 功能

这确实是函数try块的主要附加值:一个方便的地方记录“嘿,这个函数抛出了一个异常”它包含整个函数,是记录此类事件的唯一地方,但不影响普通异常处理。构造函数中的

函数尝试块不会阻止异常被抛出。这里是C++标准草案N4140的摘录,[除句柄]:

14
如果构造函数的函数try块的处理程序中出现return语句,则程序的格式不正确

15
如果控件到达构造函数或析构函数的函数try块的处理程序末尾,则当前处理的异常将被重试。否则

原因是,如果基类或任何成员构造函数抛出异常,那么整个对象的构造将失败,并且无法修复它,因此必须抛出异常

这上面有一个问题,底线是

构造函数try块处理程序只有一个目的——转换异常(也可能做日志记录或其他一些副作用)。它们对于任何其他目的都没有用处


因此,是的,您的上一个代码示例非常好。

假设您是google,有不使用异常的策略,并且您发现了一个很酷的库,但是您希望从中继承的类抛出(仅在构造函数中,不在其他任何地方)。如果你从它继承,每个使用派生类的人每次都必须使用try/catch。在这种情况下你会怎么做?似乎唯一的答案是:使用另一个库,只因为构造函数…@Phantom,或者不从它继承,将指向它的指针作为成员,并在构造函数体中初始化它。但我相信在谷歌ey无论如何都不允许你使用那个库。
struct base
{
    base() { throw std::exception(); }
};

struct derived : public base
{
    derived() try : base() { }

    catch(std::exception& e)
    {
      std::cout << "exception 1" << std::endl;
    }
};

int main()
{
    // This works fine.
    try {
       derived a;
    }
    catch(std::exception& e)
    {
      std::cout << "exception 2" << std::endl;
    }
    return 0;
}
struct base
{
    base() { throw std::exception(); }
};

struct derived : public base
{
    derived() : base() { }
};

int main()
{
    // This works fine.
    try {
       derived a;
    }
    catch(std::exception& e)
    {
      std::cout << "exception handled" << std::endl;
    }
    return 0;
}