根据《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”