placement new是指带有额外参数的operator new,最常见的的一类是额外接受一个void*的类型:void* operatornew (std::size_t size,void* pMemory) throw();
这也是placement new名称的由来,因此这个名称具体指代什么需要看语境。一、需要同时定制一个placement deletenew的过程是先调用operator new,再去执行构造函数。因此,如果在构造过程中发生异常,C++需要主动去找到对应的delete去释放已经申请的内存。对于正常的operator new,C++会使用正常的operator delete。但是对于placement new,C++会去寻找有相同类型的placement delete。另一个方面,用户在delete指针时,调用的又是正常的operator delete,因此类需要同时提供operator delete和placement delete,分别在无异常时给用户调用,以及有异常时给C++调用。class Base{public: static void* operatornew (std::size_t size,Object& obj) throw(std::bad_alloc); staticvoidoperatordelete(void* rawMemory,Onject& obj) throw(); staticvoidoperatordelete(void* rawMemory) throw();};
因为各种形式的operator delete和operator new的名称都是一样的,意味着一对定制的函数就能把global中所有类型的operator delete和operator new都遮掩了。类似:class Base{public: static void* operator new (std::size_t size,Object& obj) throw(std::bad_alloc); ...};//报错Base b = new Base;//正常Base b = new(obj) Base;
为此,我们需要将常见的operator delete和operator new都在类中重写一遍:class Base{public: //一般的operator new/delete static void* operatornew (std::size_t size) throw(std::bad_alloc); staticvoidoperatordelete(void* rawMemory) throw(); //placement new/delete static void* operatornew (std::size_t size,void* ptr) throw(); staticvoidoperatordelete(void* rawMemory,void* ptr) throw(); //nothrow new/delete static void* operatornew (std::size_t size,const std::nothrow_t& nt) throw(); staticvoidoperatordelete(void* rawMemory,const std::nothrow_t& nt) throw();};
觉得这样麻烦,亦可以将Base内的new/delete写为调用global中的版本,再继承其即可。