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(),它释放的共享Base在d2.这可以通过向Base添加新的/删除重载相同的技巧来解决.但我不确定这是最干净的解决方案,甚至是正确的解决方案(valgrind不抱怨,FWIW).我很欣赏建议或批评.
编辑:实际上,情况更糟.正如我所声称的,这个例子中的Base类不是抽象的.如果它是抽象的,通过添加一个纯虚方法,那么我就不能再应用new/delete重写技巧了,因为我不能有一个Base类型的静态变量.所以我对这个问题没有任何解决方案!
我想说这里最好的解决方案是让你的派生类成为一个真正的单例。将派生构造函数设为私有,并仅提供一个静态 Base* getInstance() 方法,该方法创建所需的对象或返回静态实例。这样,获取 D1 对象的唯一方法就是通过此方法,因为调用 new D1 是非法的。