Exceptional C++提到了以下代码
template <class T> class Stack
{
public:
Stack();
~Stack();
/*...*/
private:
T* v_; // ptr to a memory area big
size_t vsize_; // enough for 'vsize_' T's
size_t vused_; // # of T's actually in use
};
template<class T>
Stack<T>::Stack()
: v_(new T[10]), // default allocation
vsize_(10),
vused_(0) // nothing used yet
{
}
Run Code Online (Sandbox Code Playgroud)
它说如果其中一个T构造函数抛出,那么完全构造的任何T对象都被正确销毁,最后,自动调用operator delete来释放内存.这让我们防漏.
我的理解是,如果构造函数抛出异常,应用程序应该清理任何分配的资源.以上如何防漏?
引用C++ 03标准,§5.3.4/ 8:
甲新表达通过调用获得用于对象存储分配功能.如果new-expression通过抛出异常终止,它可以通过调用释放函数来释放存储.如果分配的类型是非数组类型,则分配函数的名称为
operator new
,并且释放函数的名称为operator delete
.如果分配的类型是数组类型,则分配函数的名称为operator new[]
,并且释放函数的名称为operator delete[]
.
§5.3.4/ 17:
如果上述对象初始化的任何部分通过抛出异常终止并且可以找到合适的释放函数,则调用释放函数以释放构造对象的内存,之后异常继续在上下文中传播.的新的表达.
因此,如果任何T
构造函数抛出异常,运行时将销毁T
构造函数抛出的实例的任何已创建的子对象,然后operator delete[]
作为整体调用数组,销毁任何已创建的元素并释放数组的内存.