通过引用,临时,终身问题捕获异常对象

Fre*_*red 5 c++

请考虑以下代码:

#include <iostream>
#include <stdexcept>

void foo()
{
    throw std::runtime_error("How long do I live?");
}

int main()
{
    try
    {
        foo();
    }
    catch (std::runtime_error& e)
    {
        std::cout << e.what() << std::endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么我可以通过引用捕获异常,不是std::runtime_error("How long do I live?")rvalue?

为什么异常对象在catch块中仍然存在?

究竟抛出异常对象存储在哪里?他们的一生是几岁?

Pie*_*BdR 7

在C++标准中,第15.1.4段:

除非在3.7.3.1中指出,否则将以未指定的方式分配要抛出的异常的临时副本的内存.只要存在针对该异常执行的处理程序,临时就会持续存在.特别是,如果处理程序通过执行throw而退出; 语句,将控制权传递给另一个处理程序以获得相同的异常,因此临时保留.当为异常执行的最后一个处理程序以throw以外的任何方式退出时; 临时对象被销毁,实现可能会释放临时对象的内存; 任何这种解除分配都是以未指明的方式完成的.在销毁处理程序中的exception-declaration中声明的对象后立即发生破坏.

请注意,在C++ - 标准对话中,处理程序表示catch具有正确参数类型的块.


小智 5

抛出的异常不是临时的 - 编译器生成的异常代码会保留它的永久副本.所以你可以将它绑定到非const引用.

[edit]我只是检查标准,它实际上是指临时副本.但是,临时的生命周期保证至少与异常处理程序的生命周期一样长.