main前后的异常处理

Posted

技术标签:

【中文标题】main前后的异常处理【英文标题】:Exception handling before and after main 【发布时间】:2011-01-02 20:01:12 【问题描述】:

是否可以在这些情况下处理异常:

    在进入 main() 之前从构造函数抛出 离开 main() 后从析构函数中抛出

【问题讨论】:

因此,根据所有建议,是否可以安全地得出以下结论:(1)即使在构造函数/析构函数周围使用 try-catch 块,异常仍然会被重新抛出。 (2) 如果这种情况发生在 main() 范围之外,即全局对象的初始化,或者终止期间正常对象的自动反初始化,则无法捕获异常。 不完全。 ctor 可以通过异常指示失败,因为您不能在不构造对象的情况下让 ctor 结束;因此,捕获 ctor 抛出的异常不能违反这一点。您必须从 dtor 捕获任何潜在的异常,因为 dtor 是作为堆栈展开的一部分调用的(当抛出异常时会发生这种情况)。如果你不这样做,那么你有 两个 异常同时处于活动状态,这会让你得到 std::terminate()。 我正在阅读 Stroustrup 的标题中的这个主题。从他的解释来看,对我来说,一切听起来都像是痛苦的设计。 【参考方案1】:
    您可以使用 try-catch 封装您的构造函数。 不,您应该绝不允许在析构函数中抛出异常。

如何在构造函数中嵌入 try-catch 的有趣鲜为人知的特性:

object::object( int param )
try
  : optional( initialization )

   // ...

catch(...)

   // ...

是的,这个有效的 C++。这里的额外好处是 try 将捕获由类的数据成员的构造函数抛出的异常,即使它们没有在 ctor 初始化程序中提及或没有 ctor 初始化程序:

struct Throws 
  int answer;
  Throws() : answer(((throw std::runtime_error("whoosh!")), 42)) 
;

struct Contains 
  Throws baseball;
  Contains() try  catch (std::exception& e)  std::cerr << e.what() << '\n'; 
;

【讨论】:

当我也学会了它时我很惊讶:)。这是那些鲜为人知的功能之一...... 啊,忘了可选初始化器的传递。现在它完全深奥了。 函数 try-blocks 也适用于几乎所有函数,包括 main(实际上你应该总是有一个)。 但只有在构造函数中,它们才具有包装对象初始化的真正好处。 请注意,异常将始终在构造函数的末尾重新抛出(以防止存在具有未初始化成员的对象)。【参考方案2】:

是的:不要使用危险的全局对象!

【讨论】:

这是最好的答案(在您添加“或危险的单身人士”之后),但我在接下来的 14 小时内没有投票权! +1:以 Roger 的名义——但是,我想指出,在某些情况下这是不可能的,尤其是在使用一些奇怪的 API 为您做出决定的情况下。跨度> 【参考方案3】:

有可能在构造/销毁相关对象之前设置一个异常处理程序,以便能够处理这些异常。

对于构造函数,有一些奇怪的新语法允许在构造函数中捕获异常。不确定它是如何工作的,而且它在许多编译器中并不常见。

对于析构函数,你必须将析构函数的内容包装在 try code(); catch(...) 块。这可能并不总是理想的行为,具体取决于您希望在该析构函数中实现的目标。

【讨论】:

“新”如 15 岁以上? :P 它普遍实现并且是 C++ 标准的一部分。【参考方案4】:

简短回答:不。

任何在其构造函数中抛出异常的全局对象都会导致未处理的异常(即调用terminate)。

任何在其析构函数中抛出异常的类都是损坏的类。

使用单例模式而不是全局模式将为您提供更多选择。

【讨论】:

我发现相反:单例减少选项。不过,将应用程序级对象作为局部变量放在 main 中效果很好。 @Roger 我不认为我们不同意 - 我只是说单身比全局给你更多的选择。 不,我认为与全局对象相比,单例会减少选项,因为至少对于全局对象,您可以将它们全部放在一个 TU 中以控制初始化顺序以及其他类似的事情。 哦,我们确实不同意 ;-)。只有在需要时才会创建单例,并且在极少数情况下,一个单例依赖于另一个单例,它会自动工作,而不是必须仔细排序对象实例。单例也可以对特定的代码区域保持私有,而不需要在 main.cpp 中转储。对于原始问题,单例模式的变体将允许您处理未正确构建的单例(可能会使 UI 变灰并显示错误,而不是崩溃)。

以上是关于main前后的异常处理的主要内容,如果未能解决你的问题,请参考以下文章

Spring boot 前后台分离项目 怎么处理spring security 抛出的异常

Spring boot 前后台分离项目 怎么处理spring security 抛出的异常

Spring boot 前后台分离项目 怎么处理spring security 抛出的异常

Spring boot 前后台分离项目 怎么处理spring security 抛出的异常

Spring boot 前后台分离项目 怎么处理spring security 抛出的异常

关于前后端接口的异常的处理