This page(来自C ++ in action book)显示代码:
class Link
{
friend class FreeList;
public:
Link (Link * pNext, int id)
: _pNext (pNext), _id (id) {}
Link * Next () const { return _pNext; }
int Id () const { return _id; }
// allocator
void * operator new (size_t size)
{
assert (size == sizeof (Link));
return _freeList.NewLink ();
}
void operator delete (void * mem)
{
if (mem)
_freeList.Recycle (mem);
}
static void Purge () { _freeList.Purge (); }
private:
static FreeList _freeList;
Link * _pNext;
int _id;
};
然后说
这是真的吗?我认为将使用正确大小的派生对象调用new。为什么不呢?Class Link有一个静态成员 _freeList由重载的特定于类的运算符使用 新的和删除。请注意断言 在运营商新。它保护我们免受伤害 有人称这个特别 另一个班级的操作员。怎么样 会发生什么事吗? 运营商新的和 删除是继承的。如果是一个班级 派生自Link没有覆盖 这些运营商,新的呼吁 派生类将返回一个对象 大小错误(基类大小)。
答案 0 :(得分:9)
new
表达式将导致使用正在构造的对象的正确大小调用分配函数(operator new
)。这就是size_t
的{{1}}参数的用途。
然而,示例中operator new
的特定实现只能处理统一大小的分配请求。如果派生类没有覆盖operator new
,那么operator new
的实现将被调用,其大小无法应对(又称“错误”)。
通常,完全可以为可以处理派生类的分配请求的类编写operator new
。
答案 1 :(得分:0)
如果派生类没有数据成员,那么我认为sizeof(derived)== sizeof(Link)和链接中op new中的断言不会失败。
class derived : public Link {};
derived* d = new derived(); //should call Link's op new