- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
请注意,这个问题与从异常类的构造函数中抛出异常有关,而不是从任何旧的构造函数中抛出异常。我无法在 stackoverflow 上找到重复的问题。
This article建议不要抛出这样的异常,但我对给出的技术原因表示怀疑(作者似乎在评论中回溯了原因)。
我将举一个例子,然后讨论我对正在发生的事情的解释,这意味着这样做基本上不应该有问题,至少从技术角度来看是这样。我的主要问题是我的解释是否正确,或者我是否在概念上遗漏了什么。
例子:假设我想把所有可能的异常分为两种类型,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();
}
};
现在假设我 throw User_Error( "Some useful message.");
在 User_Error::check_state()
将抛出的情况下。会发生什么?
解释:我的期望是 Coder_Error
对象将在 throw
in throw User_Error( "Some useful message.")
行是永远遇到的,因此我们不必担心同时抛出两个异常,或类似的事情。更明确地说,我希望相关步骤按以下顺序发生。
User_Error::User_Error
将被调用。
User_Error::check_state
将被调用。
Coder_Error::Coder_Error
将被调用。
将抛出第 3 步中创建的 Coder_Error
对象。
堆栈展开将开始,普通执行将停止,因此执行永远不会到达可以抛出
第 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/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!