什么时候异常对象被破坏(并且可以被控制)?

sp2*_*nny 6 c++

我正在为容器编写一个drop-replacement,我正在努力获得所有异常保证.我正在编写该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;
}
Run Code Online (Sandbox Code Playgroud)

我希望这会严重失败,因为异常可能在被认为是被处理时被破坏,这在技术上不会重新抛出.

另一个尝试是获取异常的副本,我期望切片.

有没有办法延长异常的生命周期,以便稍后重新抛出它?如果可能的话,我也希望能够重新抛出通过的异常catch(...).

Pup*_*ppy 4

即使析构函数之一抛出异常

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

对于更具体的问题,您可以使用递归留在 catch 的堆栈框架内以尝试继续删除元素,或者您也可以使用std::exception_ptrC++11 中的 and 朋友,它们旨在传输异常。