根据《Effective C++ 中文版(第三版)》所讲,语句
Widget *pw=new Widget;
“共调用了两个函数:一个是用以分配内存的operator new,一个是Widget的default构造函数。”对于前者,我们可以通过重载operator new符号,进行干预;对于后者,我们只能编写构造函数,但是无法阻止或增加执行次数,因为那是编译器自己增加的代码,用于在operator new返回的地址处开始,使用Widget的default构造函数初始化内存。
遂比着书上的例子,写了下面的例子:
#include <stdlib.h>
#include <iostream.h>
#include <memory.h>
class C{
public:
C(){
cout<<"Constructing C"<<endl;
throw 0;
}
void* operator new(size_t size)throw(){
cout<<"operator new"<<endl;
return malloc(size);
/*return 0;//将返回结果替换为0以后,
整个代码的输出仅是operator new*/
}
void operator delete(void *)throw(){
cout<<"operator delete"<<endl;
}
};
int main(){
try{
/*总是在运算符new返回的[合法]void*指针上
调用class C的构造函数.
如果构造函数抛出异常,
则调用与运算符new对应的运算符delete
operator new(size_t size)对应operator delete(void*)
operator new(size_t size,void*)对应operator delete(void*,void*)
operator new(size_t size,iostream&)对应operator delete(void*,iostream&)
以此类推,能看懂吧?:-)
*/
C *pc=new C();
}catch(int){
cout<<"Catch it!"<<endl;
}
/*
//如果是不使用try-catch包围,
//则不会输出operator delete,
//而是程序直接崩溃
C *pc=new C();
*/
return 0;
}
输出结果为:
operator new
Constructing C
operator delete
Catch it!
参考资料:
《Effective C++ 中文版,第三版》Scott Meyers著,侯捷译
之“条款52:写了placement new也要写placement delete”