【问题标题】:Overloading new operator and inheritance重载 new 运算符和继承
【发布时间】:2012-03-28 04:53:29
【问题描述】:

我知道这也许不是世界上最好的设计,但我对答案很感兴趣 没有任何实际原因。

假设我有这两个具有重载新方法的类:

class Base {
public:
operator void* new(size_t);
};

class Child : public Base {
public:
operator void* new(size_t); //THIS, i would like this to be the "original" new.
};

operator void* Base::new(size_t) {
//...
return new Child;
//...
}

我希望 Child::new 像原来的 new 一样工作,所以我可以避免使用 malloc。

有办法吗?

先谢谢了!

【问题讨论】:

  • 这个link 可能会帮助你...
  • 我不认为你的 Base::operator new 真的“有效”(例如,每次构建 Child 时它都不会被破坏)。鉴于此,很难说出您想要Child::operator new 做什么。你确定你不是在寻找工厂函数吗?
  • 好读:How should I write ISO C++ Standard conformant custom new and delete operators?。我无法理解您要达到的目标所以我克制不要将其标记为重复,我确实感觉这就是您要寻找的。​​span>

标签: c++ operator-overloading new-operator


【解决方案1】:

这不是一个正确的设计。 operator new 函数应该是 返回原始内存,而不是构造的对象。如果您的目标是 调用new Base 实际上创建一个新的Child,它不能 用 C++ 完成;通常的解决方案是在 Base;例如:

class Base
{
    //  Ban the expression `new Base`...
    void* operator new(size_t);
protected:
    virtual ~Base();  //  Ban instances on the stack.

public:
    static Base* create(/*...*/);
    //  ...
};

然后在源文件中:

class Child : public Base
{
    //  ...
};

Base* Base::create(/*...*/)
{
    return ::new Child(/*...*/);
}

(请注意,私人operator new 并没有完全禁止客户端代码 避免使用new 运算符,因为总是可以写成::new Base。)

除了声明一个私有的operator new来禁止直接分配, operator new 成员的唯一用途是从 特定池;在这种情况下,您还需要一个成员operator delete 函数将它们释放到池中。

【讨论】:

  • 哦,我明白了。看来我误解了它的用途。
【解决方案2】:

您始终可以使用语法访问 global operator new

return ::operator new( sizeof Child );

注意一元作用域运算符。此语法忽略任何类和命名空间成员,并且可以在 Base::operator newChild::operator new 中使用。

要在不使用类/命名空间成员的情况下分配和初始化对象,请使用

::new Child

除此之外……是的,成员operator new 通常是一种严重的代码气味。

【讨论】:

  • 我建议致电operator new
  • 为什么会员operator new有问题?例如,这是一种确保类使用内存池的简单方法。 (显然,operator new、成员或其他成员永远不应使用 new 运算符,因为它的作用是返回原始内存,而不是构造对象。)
  • @Potatoswatter 这不是标准所说的。当您想要一个特定于类的operator new 函数时,它必须是该类的成员或该类的基类。并且您必须提供相应的operator delete 函数。
  • @JamesKanze Nah,我错了,最好使用成员放置operator new 来调度分配器。否则,用户可能会意外使用另一个分配器。但是,它仍然可以以其他方式工作,即使包括展示位置删除。
  • @Potatoswatter 注意与展示位置删除。它仅用于new 表达式中的构造函数抛出的特殊情况。 new 表达式中使用的 operator new 函数没有被记住。
猜你喜欢
  • 1970-01-01
  • 2011-12-05
  • 2012-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多