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[]
具有相同的行为。