ISO C++的Exception Handling能够保证
1) 对象在Construct的时候发生异常, 对象的Destructor会被调用.
2) Exception发生后, 所有自动变量(on stack)的Destructor会被调用
因此下面的代码不会发生resource leak.
void foo() { MyClass B; ... ... int* array = new int[10000]; //may exception happen ... ... }
但是, ISO C++ EH不保证异常发生时处于Heap上资源的自动释放, 下面的代码可能存在Leak.
void foo() { MyClass* pb = new B(); ... ... int* array = new int[10000]; //Object B on Heap will leak if exception happened here. ... ... }
Symbian C++使用Cleanup stack可以方便简单的避免这种leak, ISO C++如何处理呢?
1) 捕获异常:
void foo() { MyClass* pb = new B(); ... ... try { int* array = new int[10000]; //Object B on Heap will leak if exception happened here. } catch (...) { delete pb; throw; } ... ... }
在异常可能发生情况较多的情况下, 每个函数都需要用try-catch包裹, 这不是一个很好的选择.
2) 使用自动指针auto_ptr.
ISO C++的自动指针是一种泛型对象, 它利用的原理是ISO C++ EH能够保证Exception发生后, 所有自动变量(on stack)的Destructor会被调用
对于MyClass的auto pointer, 其大致实现如下:
template <class T> class auto_ptr { public: auto_ptr(p) : _ptr(p) {} ~auto_ptr() { delete _ptr; } T* operator->() { return _ptr; } T& operator*() { return *_ptr; } private: MyClass* _ptr; }
使用auto pointer的代码如下所示:
void foo() { auto_ptr<MyClass> pb = new MyClass(); ... ... int* array = new int[10000]; ... ... }