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

У меня есть одноэлементный класс, определенный в файле 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();

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

0

Решение

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

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() вернуть ссылку вместо указателя.

0

Другие решения

позволить компилятору генерировать синглтон при первом использовании, инициализируя его как статический член статической функции.

Кроме того, вы можете пойти дальше и предоставить семантику значений одноэлементных объектов с нулевой стоимостью, при этом предлагая преимущества:

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

}
0

Зачем вам нужен x_interface как глобальный или статический экземпляр, так как вы можете получить экземпляр класса x из любого места в любое время, используя статический метод: create_x_instance?

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

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

0
По вопросам рекламы [email protected]