重载运算符new和匹配删除

时间:2013-05-16 19:16:32

标签: c++ inheritance new-operator delete-operator

我在子类中重载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。

1 个答案:

答案 0 :(得分:5)

基本口头禅:

没有展示位置删除表达式。

如果使用placement-new创建对象,则必须手动销毁它,然后调用释放函数:

Base * p = new (0) Derived;

p->~Derived();

Derived::operator delete(p, 0);

如果愿意,在代码中说delete base;是一种未定义的行为,因为您从未获得base作为标准new-expression的结果。您完全有可能定义了一个完全不同的放置新分配函数,并且调用标准operator delete - 释放函数可能会造成严重破坏。碰巧在你的程序中它会解决。