条款52:谢了placement new 也就同时应该写一个placement delete
如果operator new接收到的参数除了size_t之外还有其他的话,那么这个operator new实际上就是一个placement new,所以考虑下下面这样的情况:
一个可以用来记录信息的placement new:
1 class Widget{ 2 public: 3 ... 4 static void * operator new(std::size_t size, std::ostream & logStream = std::cout) 5 throw(std::bad_alloc); 6 static void * operator delete(void * pMem, std::size_t size) throw(); 7 ... 8 };
那么当我们新建一个Widget的时候:
1 Widget * wgt = new (std::cerr)Widget;
这时,如果在new的时候成功但是在构造Widget的时候失败,那么系统寻找不到相应的delete可以将分配的raw内存释放掉,这样就会引起内存泄漏了。
所以在提供placement new 的时候一定要提供相应的placement delete,这样就不会发生内存泄漏。
placement delete如下所示:
1 static void operator delete(void * pMem, std::ostream& logStream);
完成所有的要点的简单的形式是,建立一个base class, 内含有所有正常形式的new以及delete.完成所有的要点的简单的形式是,建立一个base class, 内含有所有正常形式的new以及delete.完成所有的要点的简单的形式是,建立一个base class, 内含有所有正常形式的new以及delete.
1 class StandardNewDeleteForms{ 2 public: 3 //normal new / delete 4 static void * operator new(std::size_t size) throw(std::bad_alloc) 5 { 6 return ::operator new(size); //这里使用的是全局的new 7 } 8 static void operator delete(void * pMem) throw() 9 { 10 return ::operator delete(pMem); 11 } 12 //placement new / delete 13 static void * operator new(std::size_t size, void * ptr) throw() 14 { 15 return ::operator new(size, ptr); 16 } 17 static void operator delete(void * pMem, void * ptr)throw() 18 { 19 return ::operator delete(pMem, ptr); 20 } 21 //nothrow new/delete 22 static void * operator new(std::size_t size, const std::nothrow_t & nt) throw() 23 { return ::operator new(size, nt);} 24 static void operator delete(void * pMem, const std::nothrow_t & nt) throw() 25 { return ::operator delete(pMem, nt)} 26 };
然后既可以使用继承以及using声明获得想要的new以及delete:
1 class Widget : public StandardNewDeleteForms{ 2 public: 3 using StandardNewDeleteForms::operator new; 4 using StandardNewDeleteForms::operator delete; //将他们引入作用域,以免全局的new以及delete被遮盖的掉。 5 static void * operator new(std::size_t size, 6 std::ostream & logStream) throw(std::bad_alloc); 7 static void * operator delete(void * pMem, 8 std::ostream & logStream) throw(); 9 };