最近回答了一个关于异常的问题,让我想起了一个旧问题。
下面是用c++编译的
#include <iostream>
using namespace std;
struct weird {
void danger()
{
throw *this;
}
};
int main()
{
weird object;
object.danger();
return 0;
}
但它总是会导致运行时错误。
对象不是在堆栈展开期间被抛出和保存的吗?
运行时错误闻起来像调用
terminate
,这是怎么引起的?如果
weird object
是在封闭范围(这里是全局范围)中声明的,它可以在内部范围内工作吗? (在哪里展开堆栈不会影响高级堆栈?)
最佳答案
结果是对 std::terminate()
的调用,因为从未捕获到异常。将其更改为以下内容即可正常工作:
int main() {
weird object;
try {
object.danger();
}
catch (weird &w) {
std::cout << "caught weird\n";
}
}
- Isn't the object thrown, preserved during stack unwinding?
当抛出异常时,异常抛出机制会将抛出的值复制到某个私有(private)内存中,因此“抛出”对象的生命周期无关紧要。
(当然,如果你抛出一个指针,那么指针值就会被保留,而不是指向的对象。在这种情况下,你必须确保 catch 处理程序不会对指针值做非法的事情,要么确保对象仍然存在,或者 catch 处理程序不遵循指针。)
- The runtime error smells like a call to
terminate
, how is this caused?
当抛出异常并且没有相应的捕获处理程序时,C++ 声明必须调用 std::terminate()
。负责寻找合适的捕获处理程序的异常抛出机制通过在找不到合适的捕获处理程序时调用 std::terminate()
来实现这一点。
- If
weird object
was declared in an enclosing scope (the global here) could this work in an inner scope?
它是否是全局的并不重要;无论哪种方式,抛出异常的行为(大部分)都是明确定义的。
(指定实现的一件事是如果在未找到捕获处理程序时调用 std::terminate()
之前堆栈被展开。我相信在大多数实现中堆栈不会展开这种情况。)
关于c++ - 一个物体可以抛出自己吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22261529/