条款49 Understand the behavior of the new-handler
当operator new 无法满足内存申请时,就会不断调用new-handler,直到找到足够内存,所以要如何设计一个new-handler
- 让更多内存可被使用
- 安装另一个new-handler:如果目前这个 new-handler 无法取得更多可用内存,目前这个 new-handler就可以安装另外那个 new-handler 以替换自己
- 卸除new-handler,把null指针传给set_new_handler
- 抛出bad_alloc异常
- 不返回,调用abort或者exit
只需要每个class提供自己的set_new_handler和operator new即可做到每个class专属的new-handler
Eg.
Nothrow new 是一个颇为局限的工具,因为它只适用于内存分配:后继的构造函数调用还是可能抛出异常。
条款50 Understand when it makes sense to replace new and delete
重载operator new和operator delete,为了避免或者检测一些错误,提高性能节约空间等目的
条款51 Adhere to convention when writing new and delete
编写 new 和 delete 时需固守常规
operator new
- 内存不足时需要调用new-handling函数
- 有能力供应内存就返回指针指向其内存,没能力就抛出bad_alloc异常
- 注意如果是需要0byte也要返回1byte
operator delete:在收到null指针后不做任何事
条款52 Write placement delete if you write placement new
如果 operator new接受的参数除了一定会有的那个size_t 之外还有其他,这个就是placement new。众多 placement new 版本中特别有用的一个是"接受一个指针指向对象该被构造处",那样的operator new长相如下:
void* operator new(std::size_t , void* pMemory) throw(); //placement new
在class内声明任何operator news都会遮盖上述的标准形式。所以可以建立一个base class,内含所有正常形式的new和delete
#include <iostream>
class StandardNewDeleteForms
{
public:
// normal new/delete
static void *operator new(std::size_t size) throw(std::bad_alloc) { return ::operator new(size); }
static void operator delete(void *pMemory) throw() { ::operator delete(pMemory); }
// placement new/delete
static void *operator new(std::size_t size, void *ptr) throw() { return ::operator new(size, ptr); }
static void operator delete(void *pMemory, void *ptr) throw() { ::operator delete(pMemory, ptr); }
// nothrow new/delete
static void *operator new(std::size_t size, const std::nothrow_t &nt) throw() { return ::operator new(size, nt); }
static void operator delete(void *pMemory, const std::nothrow_t) throw() { ::operator delete(pMemory); }
};
自定义的class可以继承或者使用using声明式