gpt4 book ai didi

c++ - 从 C++ 异常的构造函数中抛出异常

转载 作者:行者123 更新时间:2023-11-27 23:43:22 28 4
gpt4 key购买 nike

请注意,这个问题与从异常类的构造函数中抛出异常有关,而不是从任何旧的构造函数中抛出异常。我无法在 stackoverflow 上找到重复的问题。

This article建议不要抛出这样的异常,但我对给出的技术原因表示怀疑(作者似乎在评论中回溯了原因)。

我将举一个例子,然后讨论我对正在发生的事情的解释,这意味着这样做基本上不应该有问题,至少从技术角度来看是这样。我的主要问题是我的解释是否正确,或者我是否在概念上遗漏了什么。

例子:假设我想把所有可能的异常分为两种类型,User_ErrorCoder_Error。前者显然表明用户做了他们不应该做的事情,而后者表明一些严重的内部检查失败并且有人应该提交错误报告。这是一个(显然过于简单的)草图:

#include <stdexcept>
#include <string>
...

class Coder_Error : public std::runtime_error
{
public:
Coder_Error( const std::string& msg ) :
std::runtime_error( msg + " Please freak out and file a bug report!" )
{}
};


class User_Error : public std::runtime_error
{
protected:
static void check_state() const
{
... // May rely on static members of this class or other classes.
if ( validation_failed ) {
throw Coder_Error( "A useful description of the problem." );
}
}

public:
User_Error( const std::string& msg ) : std::runtime_error( msg )
{
check_state();
}
};

现在假设我 throw User_Error( "Some useful message.");User_Error::check_state() 将抛出的情况下。会发生什么?

解释:我的期望是 Coder_Error 对象将在 throw in throw User_Error( "Some useful message.") 行是永远遇到的,因此我们不必担心同时抛出两个异常,或类似的事情。更明确地说,我希望相关步骤按以下顺序发生。

  1. User_Error::User_Error 将被调用。

  2. User_Error::check_state 将被调用。

  3. Coder_Error::Coder_Error 将被调用。

  4. 将抛出第 3 步中创建的 Coder_Error 对象。

  5. 堆栈展开将开始,普通执行将停止,因此执行永远不会到达可以抛出第 1 步中创建的 User_Error 的地步.(我假设没有错误被捕获。)

这是正确的吗?

最佳答案

据我所知,你是正确的,评估 throw User_Error(...) 有一个定义明确的结果并且不调用 std::terminate,前提是 Coder_Error 对象被封闭的处理程序捕获。 GCC and Clang both agree .

您的推理对于 C++14 及以下版本是正确的。在 C++17 中,由于强制复制省略,User_Error 的构造函数在抛出异常的过程中被调用,即, 一旦编译器已经开始评估throw 部分,并在某处为异常对象分配了一些存储空间。但是,当构造通过第二个异常 退出时,编译器会清理该存储并继续为第二个异常寻找处理程序。无论哪种情况,结果都如您所说。

请注意,如果在异常的处理期间调用的复制构造函数通过异常退出,则将调用std::terminate(即, 因为异常对象被复制到按值捕获的处理程序中)(see example)。这与您描述的情况不同。

关于c++ - 从 C++ 异常的构造函数中抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52671326/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com