一般而言,如果基类定义了operator new,那么派生类也必须对应定义。
考虑下面的两个类
char * pAddress;
class CBase
{
public:
static void* operator new(size_t size){return pAddress;};
static void operator delete(void * p){};
};
class CDerive:public CBase
{
char buffer[1024];
public:
CDerive()
{
for(int i=0; i < 1024; i ++)
{
buffer[i] = i %26 + 'a';
}
}
};
当调用CDerive * p = new CDerive时,编译器首先尝试匹配该类自己的new,由于没有,编译器就尝试匹配在其祖先链上的new,于是调用CBase::operator new
但是基类其实不知道派生类任何信息,它仅仅根据CBase处理,因此构造了一个错误的类对象。
下面是我的测试代码,你可以发现在delete时程序报告p2指针被破坏,这就是因为CDerive得不到自己的1024字节内容,因此覆盖了后面的内容
void test()
{
char *p1, * p2;
p1 = new char[10];
memset(p1,0,10);
pAddress = new char[sizeof(CBase)];
p2 = new char[10];
memset(p2,0,10);
CDerive *pDerive = new CDerive;
TRACE(_T("%p\n"),pDerive);
delete p1;
delete p2;
delete pAddress;
}