在派生类中重写operator new/delete

Eit*_*tan 6 c++ singleton overriding memory-management new-operator

我有一个无状态的抽象基类,各种具体的类从中继承.其中一些派生类也是无状态的.因为它们中的许多都是在运行期间创建的,所以我希望通过重写operator new()/ delete()来让所有无状态派生类模拟单例来节省内存和开销.一个简化的例子看起来像这样:

#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;
}
Run Code Online (Sandbox Code Playgroud)

这个例子不工作:delete s2;失败,因为delete s1;所谓的~Base(),它释放的共享Based2.这可以通过向Base添加新的/删除重载相同的技巧来解决.但我不确定这是最干净的解决方案,甚至是正确的解决方案(valgrind不抱怨,FWIW).我很欣赏建议或批评.

编辑:实际上,情况更糟.正如我所声称的,这个例子中的Base类不是抽象的.如果它是抽象的,通过添加一个纯虚方法,那么我就不能再应用new/delete重写技巧了,因为我不能有一个Base类型的静态变量.所以我对这个问题没有任何解决方案!

zie*_*ikk 1

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