parms pa;
};
{
janitor j(parms); //无论trycode成功执行还是抛出异常,j都会被析构
trycode();
}
我们仅仅在newcopy函数里应用了try/catch,因此我们可以改写newcopy如下:
template<class t>
t* newcopy( const t* src, unsigned srcsize, unsigned destsize )
{
destsize = max( srcsize, destsize ); // basic parm check
struct janitor {
janitor( t* p ) : pa(p) {}
~janitor() { if( uncaught_exception() ) delete[] pa; }
t* pa;
};
t* dest = new t[destsize];
//如果执行到此,内存分配和各个构造函数都已成功
janitor j(dest);
copy( src, src+srcsize, dest );
// 如果程序执行到此,拷贝已经成功...否则,
// j 在栈回展(stack-unwinding)时被析构,其析构函数负责
// 回收dest以免内存泄漏
return dest;
}
前面我已经说过,我已经跟几位做过实验性速度测试的人交谈过。当没有异常发生时,try/catch通常是比较快的,而且可望更快。然而,了解这种方法还是很重要的,因为它常常带给我们更加优美更加容易维护的代码,而且一些现行的编译器对于try/catch在发生异常和不发生异常时产生的代码都不是非常高效的。