The cyclic dependency is bad:
struct Singleton2;
struct Singleton1 {
static Singleton1 const& get() {
static Singleton1 _instance;
return _instance;
}
private:
Singleton1();
Singleton2 const& _s2;
};
struct Singleton2 {
static Singleton2 const& get() {
static Singleton2 _instance;
return _instance;
}
private:
Singleton2();
Singleton1 const& _s1;
};
Singleton1::Singleton1() : _s2(Singleton2::get()) { }
Singleton2::Singleton2() : _s1(Singleton1::get()) { }
int main()
{
auto& s1 = Singleton1::get();
auto& s2 = Singleton2::get();
}
Will result in a failure (see http://liveworkspace.org/code/4rPFDo$0).
Like in all cases where you need to break cycles, make at least one link in the chain lazy.
Solve it in the obvious way by not requiring a reference to the other singleton during construction:
struct Singleton2;
struct Singleton1 {
static Singleton1 const& get() {
static Singleton1 _instance;
return _instance;
}
private:
Singleton1() {}
static Singleton2 const& getOther();
};
struct Singleton2 {
static Singleton2 const& get() {
static Singleton2 _instance;
return _instance;
}
private:
Singleton2() {}
static Singleton1 const& getOther();
};
Singleton2 const& Singleton1::getOther() { return Singleton2::get(); }
Singleton1 const& Singleton2::getOther() { return Singleton1::get(); }
int main()
{
auto& s1 = Singleton1::get();
auto& s2 = Singleton2::get();
}
Alternatively delay-initialize using boost::optional, boost::flyweight or a custom 'lazy_ptr': https://stackoverflow.com/a/878298/85371