C++:在多态单例类上重载删除

标签 c++ memory-management singleton operator-overloading dynamic-memory-allocation

假设我有以下内容:

struct Base {
  virtual ~Base() noexcept = default;
  ...
};

struct Singleton
    : public Base {
  void* operator new(size_t sz) noexcept { return instance(); }
  void operator delete(void* ptr) noexcept {
    // the body is supposed to be empty since new() doesn't allocate
    ++delete_count;
  }
  static Singleton* instance() noexcept {
    static Singleton kInstance;
    return &kInstance;
  }
  ...
};

(我使用这样的单例类来减少类似容器的多态类的开销,例如 std::vector< std::unique_ptr<Base> > ,尤其是当其中多个出现在容器中时。)

我很惊讶以下代码崩溃:

int delete_count = 0;
Singleton* s = new Singleton;
Singleton* s2 = new Singleton;
assert(s == s2);
assert(s == Singleton::instance());

delete s;
assert(1 == delete_count);
assert(s == Singleton::instance());

delete s2;  // crashes with free(): invalid pointer
assert(2 == delete_count);

有趣的是,如果我将 Singleton非多态类,即从 Base 中删除虚拟析构函数,一切正常(即使我通过添加类成员使 Base 类非空)。

有人能解释为什么会发生这种情况以及如何解决吗?

编辑:似乎改变了Singleton::delete到:

void operator delete(void* ptr) noexcept {
  ::new(ptr) Singleton;  // re-initialize using placement new
  ++delete_count;
}

让它工作,至少在 GCC 4.8.1 上

最佳答案

代码在 GCC (4.9) 和 Clang 上运行良好。 GCC 4.8.2 失败。VC++ 2013 也失败。

这是一个minimalistic code example .

您使用的是什么编译器(当然还有版本)?

关于C++:在多态单例类上重载删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24047340/

相关文章:

c++ - 在 C++ 中使用变量的值作为下一个变量的名称

c++ - 在可以转换为另一个模板类型的类模板中重载赋值运算符

linux - 如何使属于特定进程的特定内存页无效

c++ - 如何实现缓存友好的动态二叉树?

javascript - 在 JavaScript 中重新分配函数声明

c++ - C++ 中的 Python struct.pack/unpack 等价物

c++ - 80040111 ClassFactory 无法提供请求的类(HRESULT 异常 : 0x80040111 (CLASS_E_CLASSNOTAVAILABLE))

javascript - ExtJS:有没有办法处理内存管理

java - 在Java中实现单例模式与工厂模式相结合的最佳方式是什么?详细描述

iphone - 主线程上的单例类 - iPhone