静态变量初始化

时间:2013-03-04 02:13:35

标签: c++ static singleton

我有一个实现单例的模板类:

template<typename T>
class Singleton {
     static Singleton const& get() const { return _instance; }
   private:
      Singleton();
      static Singleton _instance;
};

此模板有一些专精,例如,Type1Type2。它的构造函数相互调用get()。我看到了一个问题。我们假设首先构造Singleton Type1

Singleton<Type1>::Singleton() {
   Singletion<Type2>::get();
}

因此Singleton的{​​{1}}尚未构建。 Type2将返回什么内容?

2 个答案:

答案 0 :(得分:1)

您需要在_instance函数中设置static get

template<typename T>
class Singleton {
     static Singleton const& get() const {
       static Singleton _instance;
       return _instance;
     }
   private:
      Singleton();
};

这样,实例将在第一次调用get时初始化。

答案 1 :(得分:0)

循环依赖很糟糕:

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)。

就像你需要打破周期的所有情况一样,在链中至少创建一个链接 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