当一个异常对象被销毁时(它可以被控制吗)

When is a exception object destroyed (and can it be controlled)?

本文关键字:控制 一个 异常 对象      更新时间:2023-10-16

我正在为容器编写一个drop替换将所有的异常保证落实到位。我目前正在写作clear方法,我希望它尽可能多地完成,并始终保持容器处于一致状态,即使其中一个析构函数抛出异常。我还想重新思考例外是在我清洗完之后,最好不要切片。

这就引出了一个问题;异常何时被销毁?让我们来看看一个尝试:此示例对此进行了简化。

void container::clear()
{
    bool had_exception = false;
    std::exception* exp;
    internal_set_empty(); // this cant throw
    while( ! internal_done() )
    {
        try
        {
            internal_destruct_next(); // this might throw if T::~T() throws
        }
        catch( std::exception& e )
        {
            had_exception = true;
            exp = &e;
        }
    }
    if( had_exception )
        throw *exp;
}

我预计这将严重失败,因为异常可能已被破坏当它被认为是已处理的,并且这在技术上不会重新抛出。

另一种尝试是复制异常我想会切片。

有没有办法延长异常的生存期,这样我就可以重新思考晚些时候?如果可能的话,我还希望能够重新抛出捕获的异常经由CCD_ 2。

即使其中一个析构函数抛出异常

无法完成。析构函数不是有原因的——你无法从抛出的析构函数中恢复。很明显,你不会做任何事情来清理析构函数抛出的对象——因为你怎么可能尝试这样做——但这也意味着你只是让它们处于僵尸状态。

关于更具体的问题,您可以使用递归停留在catch的堆栈框架内,以尝试不断删除元素,或者您也可以使用std::exception_ptr和C++11中的友元,它们用于传输异常。

将异常传递给调用者的当前用法是在catch块中重新抛出异常。假设你有充分的理由不这么做,唯一正确的方法就是使用std::exception_ptr。如果仅使用std::exception*,那么在您再次抛出异常之前,异常被破坏并释放其内存的风险很高。

标准C++2011草案(n4296(说在15.1抛出异常§4:异常在异常的最后一个活动处理程序通过其他任何方式退出后,对象被销毁而不是重新思考,或引用异常对象的std::exception_ptr类型的最后一个对象是已销毁,以较晚者为准。在前一种情况下,销毁发生在处理程序立即退出时在销毁处理程序中异常声明中声明的对象之后(如果有的话(。在后者在这种情况下,破坏发生在std::exception_ptr的析构函数返回之前。实施然后可以解除分配用于异常对象的存储器;任何此类解除分配都是在未指定的方式(强调我的(

相关文章: