当涉及单身对象时,克服静态初始化顺序惨败



我有一个singleton类在文件x.h

中定义
class x
{
 public:
     static x* x_instance;
     static x* create_x_instance
     {
        if(!x_instance)
            x_instance = new x;
        return x_instance;
     }
     void someMemberFunction()
  private:
  x() { //some code}
};
extern x *x_interface;     

在x.cpp中我有以下内容:

x *x::x_instance = 0;
x *x_interface = x::create_x_instance();   

在y.cpp中,在另一个单身派类的构造函数中,我有

x_interface->someMemberFunction();    

我会出现SEG故障,因为y在x之前初始化。解决这个问题的正确方法是什么?我已经阅读了许多文章,但我仍然感到困惑。

只是要清楚,使用静态函数的静态成员避免初始化顺序问题:

class x
{
 public:
     static x* get_instance()
     {
         static x* theInst = new x;
         return theInst;
     }
     void someMemberFunction();
  private:
     x() { //some code}
};

后来的代码像这样获取x

x* handle = x::get_instance();

上面的最小值,应进一步改进以管理x寿命。最好只有theImpl是静态x而不是指针到x,然后get_instance()返回引用而不是指针。

允许编译器通过将其作为静态函数的静态成员初始化而在首次使用时生成单例。

此外,您可以走得更远,并以零成本给出单身对象价值语义,而提供可能会受益:

class x
{
    struct impl
    {
        void someMemberFunction() {
        }
    };
    static impl& get_impl() {
        static impl _{};
        return _;
    }
public:
    void someMemberFunction()
    {
        return get_impl().someMemberFunction();
    }
};
int main()
{
    auto a = x();
    a.someMemberFunction();
}

为什么使用静态方法从任何时候从任何地方获得x的实例,为什么需要x_interface作为全局或静态实例:create_x_instance?

我认为在Y类中使用它的最佳方法为:

(x :: create_x_instance()) -> somememberfunction();

相关内容

  • 没有找到相关文章

最新更新