2

我在子类中重载了 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)这里没有调用匹配的删除运算符 ( )?无论我做什么,我都无法获取调用匹配运算符删除的代码。

4

1 回答 1

5

基本口头禅:

没有放置删除表达式。

如果你使用placement-new创建一个对象,你必须手动销毁它,然后调用deallocation函数:

Base * p = new (0) Derived;

p->~Derived();

Derived::operator delete(p, 0);

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

于 2013-05-16T19:29:06.270 回答