Преодоление статического фиктивного порядка инициализации, когда задействован одноэлементный объект

У меня есть одноэлементный класс, определенный в файле xh

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();    

Я получаю ошибку сегмента, потому что у инициализируется до х. Как правильно решить эту проблему? Я прочитал много статей по этому поводу, но я все еще в замешательстве.

3 ответа

Решение

Просто чтобы прояснить, использование статического члена статической функции позволяет избежать проблем порядка инициализации:

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_interface как глобальный или статический экземпляр, так как вы можете получить экземпляр класса x из любого места в любое время, используя статический метод: create_x_instance?

Я думаю, что лучший способ использовать его в классе у как:

(Х::create_x_instance())->someMemberFunction();

Другие вопросы по тегам