简答:
new 和 delete 运算符在类范围内被重载,以优化特定类对象的分配。但是由于 Inheritance 这样的某些野兽,可能会出现特殊情况,这可能导致分配请求超过类大小本身,因为 new 和 delete 重载的目的是针对大小为 @987654327 的对象进行特殊调整@,没有更大或更小,这些重载的运算符应该将所有其他wrong sized 内存请求转发到::operator new 和::operator delete,为了能够这样做,需要将大小参数作为参数传递。
长答案:
考虑一个特殊场景:
class Base
{
public:
static void * operator new(std::size_t size) throw(std::bad_alloc);
};
class Derived: public Base
{
//Derived doesn't declare operator new
};
int main()
{
// This calls Base::operator new!
Derived *p = new Derived;
return 0;
}
在上面的示例中,由于继承了派生类Derived,继承了Base类的new运算符。这使得在基类中调用 operator new 为派生类的对象分配内存成为可能。我们的 operator new 处理这种情况的最佳方法是将此类请求“错误”内存量的调用转移到标准 operator new,如下所示:
void * Base::operator new(std::size_t size) throw(std::bad_alloc)
{
if (size != sizeof(Base)) // if size is "wrong," i.e != sizeof Base class
{
return ::operator new(size); // let std::new handle this request
}
else
{
//Our implementation
}
}
在重载delete 运算符时,还必须确保由于特定类的运算符 new 将“错误”大小的请求转发到 ::operator new,因此必须将“错误大小”的删除请求转发到 ::operator delete,由于原始运营商保证以符合标准的方式处理这些请求。
所以自定义的delete 运算符将是这样的:
class Base
{
public:
//Same as before
static void * operator new(std::size_t size) throw(std::bad_alloc);
//delete declaration
static void operator delete(void *rawMemory, std::size_t size) throw();
void Base::operator delete(void *rawMemory, std::size_t size) throw()
{
if (rawMemory == 0)
{
return; // No-Op is null pointer
}
if (size != sizeof(Base))
{
// if size is "wrong,"
::operator delete(rawMemory); //delegate to std::delete
return;
}
//If we reach here means we have correct sized pointer for deallocation
//deallocate the memory pointed to by rawMemory;
return;
}
};
进一步阅读:
以下 C++-Faq 条目讨论了以符合标准的方式重载 new 和 delete ,可能适合您阅读:
How should i write iso c++ standard conformant custom new and delete operators?