如何通过引用捕获异常来解决局部变量问题



在更有效的c++第13项中,第13项:通过引用捕获异常。

还有一点要说——要通过指向工作的指针捕获异常,程序员必须以确保控件离开函数后对象存在的方式定义异常对象。全局对象和静态对象工作正常。

//通过指针捕获异常的示例

class exception { ... };          // from the standard C++
void someFunction()
{
    static exception ex;            // exception object
    ...
    throw &ex;                      // throw a pointer to ex
    ...
}
void doSomething()
{
    try 
    {
        someFunction();               // may throw an exception*
    }
    catch (exception *ex) 
    {    // catches the exception*;
        ...                           // no object is copied
    }
}

我的疑问是,在通过引用捕获异常的情况下,它有什么不同?若它是一个局部变量(不是静态的或全局的),那个么一旦控件离开函数,对象就不存在了。那么如何通过引用捕获异常来解决这个问题呢?

要捕获指针,必须抛出一个指针。若要捕获引用,请按值抛出对象。给定对象名称的throw表达式生成对象的副本;它不会将其论点解释为引用。

抛出的副本被称为异常对象,它位于运行库维护的特殊分配区域中。它的析构函数在异常传播完成时被调用,异常传播可能在调用堆栈的任何位置。C++11提供了额外的工具,可以使用引用计数语义手动控制异常对象的生存期。

如果按值捕获,则在进入按值捕获的catch块时会生成另一个副本,并且在离开该catch块时会销毁第二个副本,即使异常传播到另一个封闭的catch块。外部catch将在没有由内部catch应用任何修改的情况下看到原始异常对象。

通过const引用捕获的习惯用法实现了让catch块通信的能力。


顺便说一句,由于指针抛出无法处理内存不足的错误,因此它从根本上被破坏了。如果尝试使用new分配异常对象,但没有更多内存,则std::bad_alloc将在程序到达throw表达式之前劫持程序。该库提供了一种分配异常的替代方法,以应对内存不足的情况。

最新更新