struct base
{
base() { throw std::exception(); }
};
struct derived : public base
{
derived() try : base() { }
catch (std::exception& e)
{
std::cout << "exception handled" << std::endl;
}
};
int main()
{
derived a; // My app crashes.
return 0;
}
Run Code Online (Sandbox Code Playgroud)
不是我的应用程序写"异常处理"并继续运行?
我发现的唯一解决方案是a在try/catch块中包围" " 的构造.但是,如果我这样做,那么首先在构造函数中使用try/catch有什么意义呢?我猜也许它的用途是清理可能已分配的成员变量?既然没有调用析构函数?
以下工作,但处理异常2次.
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;
}
Run Code Online (Sandbox Code Playgroud)
我只是想问自己为什么我不应该简单地为构造函数躲避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;
}
Run Code Online (Sandbox Code Playgroud)
构造函数中的function-try-block不会阻止抛出异常.以下是C++标准草案N4140的摘录,[except.handle]:
14如果返回语句出现在构造函数的function-try-block的处理程序中,则程序格式错误.
15如果控制到达构造函数或析构函数的function-try-block的处理程序的末尾,则重新抛出当前处理的异常.除此以外, ...
这样做的原因是,如果基类或任何成员构造函数抛出异常,则整个对象的构造失败,并且无法修复它,因此必须抛出异常.
这有一个GOTW,底线是
构造函数try-try-block处理程序只有一个目的 - 转换异常.(也许要做日志记录或其他一些副作用.)它们对任何其他目的都没用.
所以,是的,你的最后一个代码样本非常好.