假设我有以下内容:
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/