在回答有关异常的最新问题时,使我想起了一个旧查询。

以下在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";
        }
    }
    



    当引发异常时,异常引发机制将所引发的值的副本复制到某个地方的某些私有(private)内存中,因此“被引发”对象的生存期无关紧要。

    (当然,如果您抛出一个指针,那么该指针值将被保留,而不是指向对象。)在这种情况下,您必须通过确保该对象仍然存在,或通过确保该对象仍然存在,来确保捕获处理程序不会对该指针值进行非法操作。捕获处理程序不尊重指针。)



    当引发异常并且没有相应的捕获处理程序时,C++指出必须调用std::terminate()。负责查找合适的捕获处理程序的异常抛出机制通过在找不到合适的捕获处理程序时调用std::terminate()来实现此目的。



    是否全局性都无关紧要;抛出异常的行为(大多数)是用两种方法定义的。

    (指定实现的一件事是,如果在未找到捕获处理程序的情况下在调用std::terminate()之前取消堆栈的堆栈。我相信在大多数情况下,在这种情况下不会取消堆栈的堆栈。)

    09-06 12:50