定制new和delete
这部分主要介绍Operator new
和Operator delete
。
回顾一下,一直熟知的new/delete其实全称是new operator
/delete operator
是操作符。以new
例,它包含了两个操作:第一部分是分配足够的内存以便容纳所需类型的对象。第二部分是它调用构造函数初始化内存中的对象。new操作符总是做这两件事情,你不能以任何方式改变它的行为。
条款49:了解new-handler的行为
operator new 无法满足某一内存分配需求的时候,它会抛出异常。
再抛出异常之前,它会先调用一个客户指定的错误处理函数即new-handler
namespace std{
typedef void (*new_handler)();
new_handler set_new_handler(new_handler p) throw();
};
可以看出new_handler是一个函数指针类型,该函数指针指向的函数返回空参数也为空。而set_new_handler
的操作是从参数设置一个新的new_handler
并返回一个旧的new_handler
。
在STL中有set_new_handler(0);
就是强制卸载异常处理函数,当内存分配不够时直接抛出std::bad_alloc异常。
void outOfMem()
{
std::cerr << "out of mem" << endl;
throw bad_alloc();
//std::abort();
}
int main()
{
std::set_new_handler(outOfMem);
while (true)
{
int *p = new int[100000];
}
system("pause");
return 0;
}
设计良好的new-handler,本条款给出以下结论:
1.让更多内存可被使用
2.安装另一个new-handler(调用set_new_handler
)
3.写出new-handler:set_new_handler(0);
4.抛出异常:throw std::bad_alloc();
5.直接std::abort()
首先是一个RAII管理的例子。
class NewHandlerHolder :public boost::noncopyable
{
public:
explicit NewHandlerHolder(new_handler nh) :handler(nh){}
~NewHandlerHolder(){ set_new_handler(handler); }
private:
new_handler handler;
};
class Widget{
public:
static std::new_handler set_new_handler(std::new_handler p) throw();
static void* operator new (std::size_t size) throw(std::bad_alloc);
private:
static std::new_handler currentHandler;
};
//static 成员在class之外进行初始化
std::new_handler currentHandler = 0;
std::new_handler Widget::set_new_handler(std::new_handler p)throw()
{
new_handler oldHandler = currentHandler;
currentHandler = p;
return oldHandler;
}
void *Wid