循環依存は良くありません:
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();
}
失敗します ( http://liveworkspace.org/code/4rPFDo$0を参照)。
サイクルを中断する必要があるすべての場合と同様に、チェーン内の少なくとも 1 つのリンクをlazyにします。
構築中に他のシングルトンへの参照を必要としないことで、明白な方法で解決します。
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();
}
あるいは、boost::optional、boost::flyweight、またはカスタム 'lazy_ptr' を使用して遅延初期化します: https://stackoverflow.com/a/878298/85371