vc中new和delete操做符的重载

在C++中重载new和delete操做符能够给程序带来更灵活的存储控制,对于游戏设计等对效率要求较高的应用而言是必不可少的。通常的C++书籍中也会介绍它们的应用和实现,然而在VC中实现却有几个必须注意的地方,不然编译会出现问题。函数

1. 实现

首先,vc在每一个自动生成的cpp文件中都会加入以下代码:测试

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
字体

从上面红色的字体能够看出,这时的new在debug模式下被定义成了DEBUG_NEW,因此实现new函数的代码应该放在此定义以前,不然编译会报错。this

那么DEBUG_NEW又是什么东西呢?在afx.h文件中能够找到答案:spa

#define DEBUG_NEW new(THIS_FILE, __LINE__)debug

于是,在debug模式下若是咱们调用以下代码:设计

CWnd* pWnd = new CWnd;游戏

就变成了文档

CWnd* pWnd = new(THIS_FILE, __LINE__) CWnd;原型

上面的代码至关于调用了new(sizeof(CWnd), THIS_FILE, __LINE__)函数,它的原型为:

void* operator new(size_t, LPCTSTR, int);

因此在debug模式下咱们的new操做符必须定义为如上形式。

2. 几个问题

2.1 delete匹配问题

若是实现了void* operator new(size_t, LPCTSTR, int)操做符,最好是同时实现与之相对应的

void operator delete(void* p, LPCTSTR, int)

操做符,不然编译器会报一个警告错误:no matching operator delete found; memory will not be freed if initialization throws an exception。

2.2 成员new操做符重载

若是重载了类的new和delete操做符,必须将他们声明为静态成员。这是由于对于非静态的成员函数,编译器会在其末尾添加一个this参数;另外,调用new的时候,类尚未构造。以上都致使了对静态声明的要求。

2.3 全局new操做符重载

若是要重载全局的new和delete操做符,只需实现如下函数(release模式下):

inline void * __cdecl operator new (size_t size);
inline void __cdecl operator delete (void *p);

不须要进行声明,只要在某个地方实现上述函数,那么全部的new操做都会调用咱们实现的函数进行。但在release模式下有个问题:new和delete的调用次数不一致。在我实现的一个测试程序中(vc6.0,缺省自动生成的多文档程序),new被调用了5次,而delete只被调用了3次,最开始两次调用的new操做没有相应的delete操做。不知道是否是调用了其余的delete原型。

相关文章
相关标签/搜索