【发布时间】:2019-03-11 07:09:30
【问题描述】:
请注意,这个问题与从异常类的构造函数 中抛出异常有关,而不是从任何旧的构造函数中抛出异常。我在 stackoverflow 上找不到重复的问题。
This article 建议不要抛出这样的异常,但我对给出的技术原因持怀疑态度(作者似乎在 cmets 中回溯了原因)。
我将举一个例子,然后讨论我对正在发生的事情的解释,这意味着这样做基本上不应该有问题,至少从技术角度来看是这样。我的主要问题是我的解释是否正确,或者我是否在概念上遗漏了什么。
示例:假设我想将所有可能的异常分为两种类型,User_Error 和Coder_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();
}
};
现在假设我在User_Error::check_state() 将抛出的情况下执行throw User_Error( "Some useful message." );。会发生什么?
解释: 我的期望是Coder_Error 对象会在遇到throw User_Error( "Some useful message." ) 行中的throw 之前被抛出,因此我们不必担心两个异常同时被抛出,或类似的东西。更明确地说,我希望相关步骤按以下顺序发生。
User_Error::User_Error将被调用。User_Error::check_state将被调用。Coder_Error::Coder_Error将被调用。第 3 步中创建的
Coder_Error对象将被抛出。堆栈展开将开始,普通执行将停止,因此执行将永远不会达到在步骤 1 中创建的
throwUser_Error的程度。(我假设没有错误出现被抓住了。)
这对吗?
【问题讨论】:
-
并不是说这是不可能的,但我很难想到一个实际情况,在这种情况下,需要有目的地隐藏具有不同类型的异常 sometimes 。
-
如果
Coder_Error表示编程错误,那么从std::logic_error继承可能更直观,因为它更能代表这种情况。std::runtime_error与意外情况相关联,而std::logic_error与编程错误相关联,并且更难且更不容易从中恢复。 -
如果您有类似
throw User_Error ();和User_Error的投掷物,预计会遇到颠簸。我不会这样做。 -
我不确定它是否符合条件,但[except.throw]/7 可能与此处相关。
-
如果你想抛出一个可能会抛出自身的类型,那么请相应地命名它...
throw up();
标签: c++ exception constructor throw