我在子类中重载operator new / delete,我注意到一个对我来说似乎很奇怪的行为。请看下面的示例代码:
#include <stdlib.h>
#include <stdio.h>
class Base
{
public:
virtual ~Base()
{
}
};
class Derived : public Base
{
public:
void* operator new(unsigned int size, int capacity)
{
printf("> new(unsigned int, int)\n");
return malloc(sizeof(Derived));
}
void operator delete(void* ptr, int)
{
printf("> delete(void*, int)\n");
free(ptr);
}
void operator delete(void* ptr)
{
printf("> delete(void*)\n");
free(ptr);
}
};
int main(int argc, char** argv)
{
Base* base = new (0) Derived();
delete base;
return 0;
}
使用Visual Studio 2010编译时,此代码生成以下输出:
> new(unsigned int, int)
> delete(void*)
为什么匹配的删除操作符(Derived::operator delete(void*, int)
)不会在此处调用?无论我做什么,我都无法获取代码来调用匹配的运算符delete。
答案 0 :(得分:5)
基本口头禅:
没有展示位置删除表达式。
如果使用placement-new创建对象,则必须手动销毁它,然后调用释放函数:
Base * p = new (0) Derived;
p->~Derived();
Derived::operator delete(p, 0);
如果愿意,在代码中说delete base;
是一种未定义的行为,因为您从未获得base
作为标准new-expression的结果。您完全有可能定义了一个完全不同的放置新分配函数,并且调用标准operator delete
- 释放函数可能会造成严重破坏。碰巧在你的程序中它会解决。