我有以下类试图实现一个通用的 Singleton。
struct BaseObject
{
virtual ~BaseObject() {}
};
class _helper
{
private:
template<typename T> friend class Singleton;
set<BaseObject*> _s;
static _helper& _get()
{
static _helper t;
return t;
}
_helper()
{
cout<<" _helper ctor"<<endl;
}
~_helper()
{
cout<<" _helper dtor"<<endl;
//assert(_s.empty());
}
};
// Singleton<foo>::Instance() returns a unique instance of foo
template <typename T>
class Singleton : virtual private T
{
public:
static T& Instance()
{
static Singleton<T> _T;
return _T;
}
private:
Singleton()
{
cout<<"inserting into helper "<<typeid(T).name()<<" ptr "<<this<<endl;
assert(!_helper::_get()._s.count(this));
_helper::_get()._s.insert(this);
}
~Singleton()
{
cout<<"erasing from helper "<<typeid(T).name()<<" ptr "<<this<<endl;
assert(_helper::_get()._s.count(this));
_helper::_get()._s.erase(this);
}
};
现在,如果我调用
Singleton< bar>::Instance()
,然后调用Singleton< foo>::Instance()
,我应该看到以下输出: inserting into helper 3bar ptr 0x509630
_helper ctor
inserting into helper 3foo ptr 0x509588
erasing from helper 3foo ptr 0x509588
erasing from helper 3bar ptr 0x509630
_helper dtor
然而,在某些情况下,我看到以下内容:
inserting into helper 3bar ptr 0x509630
_helper ctor
inserting into helper 3foo ptr 0x509588
erasing from helper 3bar ptr 0x509630
_helper dtor
erasing from helper 3foo ptr 0x509588
请注意,在第二种情况下,
bar
和foo
的销毁顺序与它们构造的顺序相同。当foo
和bar
单例在共享库(.so)中作为静态引用实例化时,似乎会发生这种情况。static bar& b = Singleton<bar>::Instance();
static foo& f = Singleton<foo>::Instance();
有什么想法是它为什么会这样做?
Singleton<foo>
和Singleton<bar>
之前构造了Singleton<bar>
,并且在Singleton<foo>
和Singleton<bar>
之前析构了Singleton<bar>
,而它应该是这样的(缩写):S<bar>,S<foo> => ~S<foo>,~S<bar>
。那就是不一致性所在,对于这些运行,实现似乎没有产生正确的终止代码。 - David Rodríguez - dribeas