I have the following classes that try to implement a generic 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);
}
};
Now if I call Singleton< bar>::Instance()
followed by Singleton< foo>::Instance()
, I should see the following output:
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
However in some cases, I see the following:
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
Note that in the second case, bar
and foo
got destructed in the same order as they were constructed. This seems to happen when the foo
and bar
singletons are instantiated inside a shared library(.so) as static references:
static bar& b = Singleton<bar>::Instance();
static foo& f = Singleton<foo>::Instance();
Any ideas why it would do that?