在多态类上解析运算符删除的特定于类的重载的规则是什么?

时间:2015-03-07 21:56:43

标签: c++ operator-overloading

This cppreference.com page说:

  

delete表达式查找适当的释放函数   首先在类范围中命名,从最派生的类型开始   如果类是多态的,那么在全局范围内。注意,   根据名称查找规则,声明的任何释放函数   class scope隐藏所有全局释放函数。删除时   多态对象,即使可以执行不同的功能   在运行时,必须是静态可见的operator delete版本   可以访问以便编译。

所以我写了一个程序来测试这个:

main.cpp中:

#include "Factory.h"

int main()
{
    using namespace std;

    Base *b1 = getBase();
    delete b1;

    Base *b2 = getBaseArray(1);
    delete[] b2;
}

Factory.h:

#ifndef FACTORY_H_INCLUDED
#define FACTORY_H_INCLUDED

#include "Base.h"

Base* getBase();
Base* getBaseArray(std::size_t);

#endif // FACTORY_H_INCLUDED

Factory.cpp:

#include "Factory.h"
#include "Child.h"

Base* getBase()
{
    return new Child;
}

Base* getBaseArray(std::size_t s)
{
    return new Child[s];
}

Base.h:

#ifndef BASE_H_INCLUDED
#define BASE_H_INCLUDED

#include <cstddef>

class Base
{
public:
    virtual ~Base() {}
    static void* operator new(std::size_t sz);
    static void* operator new[](std::size_t sz);
    static void operator delete(void *ptr, std::size_t sz);
    static void operator delete[](void *ptr, std::size_t sz);
};

#endif // BASE_H_INCLUDED

Base.cpp:

#include <iostream>

#include "Base.h"

void* Base::operator new(std::size_t sz)
{
    std::cout << "Base operator new called" << std::endl;
    return ::operator new(sz);
}
void* Base::operator new[](std::size_t sz)
{
    std::cout << "Base operator new[] called" << std::endl;
    return ::operator new(sz);
}
void Base::operator delete(void *ptr, std::size_t sz)
{
    std::cout << "Base operator delete called" << std::endl;
    ::operator delete(ptr);
}
void Base::operator delete[](void *ptr, std::size_t sz)
{
    std::cout << "Base operator delete[] called" << std::endl;
    ::operator delete(ptr);
}

Child.h:

#ifndef CHILD_H_INCLUDED
#define CHILD_H_INCLUDED

#include "Base.h"

class Child : public Base
{
public:
    virtual ~Child() {}
    static void* operator new(std::size_t sz);
    static void* operator new[](std::size_t sz);
    static void operator delete(void *ptr, std::size_t sz);
    static void operator delete[](void *ptr, std::size_t sz);
};

#endif // CHILD_H_INCLUDED

Child.cpp:

#include <iostream>

#include "Child.h"

void* Child::operator new(std::size_t sz)
{
    std::cout << "Child operator new called" << std::endl;
    return ::operator new(sz);
}
void* Child::operator new[](std::size_t sz)
{
    std::cout << "Child operator new[] called" << std::endl;
    return ::operator new(sz);
}
void Child::operator delete(void *ptr, std::size_t sz)
{
    std::cout << "Child operator delete called" << std::endl;
    ::operator delete(ptr);
}
void Child::operator delete[](void *ptr, std::size_t sz)
{
    std::cout << "Child operator delete[] called" << std::endl;
    ::operator delete(ptr);
}

GCC 4.9.1的结果似乎与cppreference.com的delete页面一致,但与delete[]的页面不一致:

Child operator new called
Child operator delete called
Child operator new[] called
Base operator delete[] called

这是对的吗?我期待delete[]具有相同的行为。

0 个答案:

没有答案