对于 new 关键字,编译器会将其转化为如下代码

Complex* pc = new Complex(1,2);

// 转化为
Complex *pc;
try {
	void* mem = operator new(sizeof(Complex));  // 调用global operator new 方法,该方法可被重载
	pc = static_case<Complext*>(mem);
	pc->Complex::Complex(1,2);  // 调用Complext的构造函数,注意标准中只有编译器可以像这样调用
	// 如果想要调用 ctor, 可以用以下方式 placement new
	// new(pc)Complext(1,2);
} catch (std::bad_alloc) { 
	// 内存分配失败,就不执行 ctor
}

// 源代码
// 对于全局的 new 方法 operator new, 可以参考如下代码
void *operator new(size_t size, const std::nothrow_t&) _THROW0() {
	// 尝试分配内存
	void *p;
	while ((p == malloc(size)) === 0) {
		// 分配内存失败
		_TRY_BEGIN
			// 调用自定义的_callnewh函数,进行释放内存操作, 返回为0说明释放失败
			if (_callnewh(size) === 0) break;
		_CATCH(std::bad_alloc) return (0);  // 返回一个空指针 
		_CATCH_END;
	}
	return (p);
}

而对于 delete 关键字,编译器会转化为如下代码

delete pc;

// 转化为
pc->~Complext();  // 调用析构函数, 可以直接调用
operator delete(pc);  // 释放内存

void __cdecl operator delete(void* p) _THROW0() { free(p); }

关于 bad_alloc

当 operator new 没能力为你分配你所申请的内存时,会抛出一个异常 std::bad_alloc 。某些老旧的编译器则是会返回0,表示创建失败。你仍可以通过以下方式显示指定,令编译器返回0。

new (nothrow) Foo;

关于 new handler

在上面可以看到,当调用 ::operator new 中的 malloc 失败时,会调用一次自定义的 _callnewh 函数,这个函数被称之为 new_handler。这个函数的方法名如下:

typedef void (*new_handler)();  // 声明了一个 new_handler 的方法格式。没有返回值也没有参数

设置 new_handler 的方式如下

new_handler set_new_handler(new_handler p) throw();

设计良好的 new_handler 函数只有两个选择: