在派生类中重写运算符new/delete [英] Overriding operator new/delete in derived class

查看:110
本文介绍了在派生类中重写运算符new/delete的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个无状态的抽象基类,各种具体的类都继承自该基类.这些派生类中的一些也是无状态的.因为它们中的许多是在运行期间创建的,所以我想通过重写运算符new()/delete()来使所有无状态派生类都模拟一个单例来节省内存和开销.一个简化的示例如下所示:

I have a stateless, abstract base class from which various concrete classes inherit. Some of these derived classes are stateless as well. Because many of them are created during a run, I'd like to save memory and overhead by having all stateless derived classes emulate a singleton, by overriding operator new()/delete(). A simplified example would look something like this:

#include <memory>

struct Base {
  virtual ~Base() {}
 protected:
  Base() {}   // prevent concrete Base objects
};

struct D1 : public Base {  // stateful object--default behavior
  int dummy;
};

struct D2 : public Base {  // stateless object--don't allocate memory
  void* operator new(size_t size)
  {
    static D2 d2;
    return &d2;
  }
  void operator delete(void *p) {}
};

int main() {
  Base* p1 = new D1();
  Base* p2 = new D1();
  Base* s1 = new D2();
  Base* s2 = new D2();
  delete p1;
  delete p2;
  delete s1;
  delete s2;
  return 0;
}

此示例不起作用:delete s2;失败,因为delete s1;调用了~Base(),从而在d2中释放了共享的Base.这可以通过向Base添加具有新的/删除的重载的相同技巧来解决.但我不确定这是最干净的解决方案,甚至是正确的解决方案(valgrind不会抱怨,FWIW).我将不胜感激建议或批评.

This example doesn't work: delete s2; fails because delete s1; called ~Base(), which deallocated the shared Base in d2. This can be addressed by adding the same trick with new/delete overloading to Base. But I'm not sure this is the cleanest solution, or even a correct one (valgrind doesn't complain, FWIW). I'd appreciate advice or critique.

实际上,情况更糟.正如我所声称的,此示例中的Base类不是抽象的.如果通过添加纯虚拟方法将其抽象化,那么我将无法再应用new/delete覆盖技巧,因为我无法拥有Base类型的静态变量.所以我没有解决这个问题的方法!

edit: actually, the situation is worse. The Base class in this example isn't abstract, as I claimed. If it's made abstract, through the addition of a pure virtual method, then I can no longer apply the new/delete overriding trick, because I cannot have a static variable of type Base. So I don't have any solution for this problem!

推荐答案

我想说的最好的解决方案是使派生类成为实际的单例.将派生的构造函数设为私有,仅提供一个静态Base * getInstance()方法即可创建所需的对象或返回静态实例.这样,获取D1对象的唯一方法就是通过此方法,因为调用新D1将是非法的.

I would say the best solution here is to make your derived class an actual singleton. Make your derived constructor private and just provide a static Base* getInstance() method that either creates the required object or returns the static instance. This way the only way to get a D1 object would be via this method since calling new D1 would be illegal.

这篇关于在派生类中重写运算符new/delete的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆