析构函数中的异常

Ste*_*eng 6 c++

在我的析构函数中,我必须清理一些资源.假设我有三次调用以清除可能抛出的资源.因为让异常离开析构函数不好,我的设计模式应该是什么?显然,下面的方式是不可扩展的.

谢谢.

class B::~B(){

try{
   clearResourceA()
 }
 catch{
     try{
         clearResourceB();
        } 
     catch{
         clearResourceC();
     }
     clearResourceC();
 }
clearResourceB();
    .
    .
}
Run Code Online (Sandbox Code Playgroud)

Ben*_*oit 10

为什么不:

try{clearResourceA();} catch(...){}
try{clearResourceB();} catch(...){}
try{clearResourceC();} catch(...){}
Run Code Online (Sandbox Code Playgroud)


Ste*_*sop 5

将每个资源封装在一个类中,该类在其析构函数中清除它们(使用周围的try/catch):

struct ProperlyManagedA {
    // some means of using the resource - a rudimentary way is this:
    A &getA() { return a; }
    const A &getA() const { return a; }
    // cleanup
    ~ProperlyManagedA() { 
        try {
            a.clear(); // whatever it is ClearResourceA actually does
        } catch (...) {}
    }
  private:
    A a;
}
Run Code Online (Sandbox Code Playgroud)

shared_ptr具有自定义删除器的A 是实现此目的的一种方法,而无需为每种类型的资源创建整个类.

根据抛出的内容,您可以改进丢弃异常(例如记录问题).

更好的是,修改资源A,B和C,以便他们在自己的析构函数中清除自己.但这可能是不可能的.

无论哪种方式,您都可以根据需要将尽可能多的此类资源放在一个类中,而无需向类的析构函数添加任何代码.这是"可扩展性".RAII的重点是,资源的每个用户都不必编写清理代码才能正确使用资源.


Mic*_*eyn 2

使用 catch-all(即 catch (...))捕获任何可能在析构函数中抛出的异常,并尽力处理抛出的异常。确保没有异常从析构函数中传播出来,catch-all 将帮助您防止这种情况。