【问题标题】:inherit operator new from base class从基类继承运算符 new
【发布时间】:2011-01-16 11:39:46
【问题描述】:

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;
};

然后说

类链接有一个静态成员 _freeList 由重载的类特定运算符使用 新建和删除。注意断言 在运营商新。它保护我们免受 有人称这个特别 不同类的运算符。如何 那会发生吗? 新运营商和 删除是继承的。如果一个班级 派生自 Link 没有覆盖 这些运营商,新呼吁 派生类将返回一个对象 大小错误(基类大小)。

这是真的吗?我认为 new 将以正确大小的派生对象调用。为什么不呢?

【问题讨论】:

    标签: c++ inheritance memory-management


    【解决方案1】:

    new 表达式将导致调用分配函数 (operator new),并使用正确大小来构造对象。这就是operator newsize_t 参数的用途。

    然而,示例中operator new 的特定实现只能处理统一大小的分配请求。如果派生类没有覆盖operator new 此实现 operator new 将使用它无法处理的大小(也称为“错误”)调用。

    一般来说,为可以处理派生类分配请求的类编写operator new 是完全可能的。

    【讨论】:

    • @zaharpopov:也许不是错误,而是一种非常误导的方式。
    • 这个实现中的什么使得无法为派生类分配?怎么写正确?
    • @zaharpopv: operator delete 只是将内存块回收到空闲列表中,而不管大小,operator new 使用回收块或FreeList:::NewLink 仅使用sizeof(Link) 内存块。为什么FreeLink 实际上并没有像评论建议的那样直接使用::operator new,而不是::new char[],我不知道。
    【解决方案2】:

    如果派生类没有数据成员,那么我认为 sizeof(derived) == sizeof(Link) 并且 Link 中 op new 中的断言不会失败。

    class derived : public Link {};
    
    derived* d = new derived(); //should call Link's op new 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-12
      • 2011-12-05
      • 1970-01-01
      • 2015-06-27
      • 2011-07-08
      • 2023-04-02
      相关资源
      最近更新 更多