2010-02-17 2 views
3

У меня естьC++ одноточечно порядок инициализации

class Foo 
class Bar 

Теперь я хочу

Foo* Foo::singleton = new Foo(); 
Bar* Bar::singleton = new Bar(); 

обоим инициализирован

int main() 

называется.

Кроме того, я хочу

Foo::singleton 

инициализировать перед тем

Bar::singleton 

Есть в любом случае я могу гарантировать, что?

Спасибо!

ответ

2

Смотрите также Static variables initialisation order

Для использования GCC init_priority:

http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html

работы через различные единицы перевода. Так что ваш код будет гласить:

Foo* Foo::singleton __attribute__ ((init_priority (2000))) = new Foo(); 
Bar* Bar::singleton __attribute__ ((init_priority (3000))) = new Bar(); 

У меня нет под рукой НКУ прямо сейчас, поэтому я не могу проверить это, но я использовал его раньше. Другим простым и более портативным решением является предотвращение статической инициализации и явное создание синглетонов в определенном месте внутри основного.

// Nothing in static area 

void main(void) 
{ 
    // Init singletons in explicit order 
    { 
    Foo* Foo::singleton = new Foo(); 
    Bar* Bar::singleton = new Bar(); 
    } 

    // Start program execution 
    ... 
} 

Помните, что все будет получить так же, как угловатое с одиночками на пути выхода из программы, а также, поэтому его часто лучше, чтобы сделать его явным.

3

Глобальные переменные (такие как одиночные числа), которые определены в одной и той же единице перевода, инициализируются в том порядке, в котором они определены. Поэтому поместите определение обоих синглетонов в один и тот же исходный файл в правильном порядке.

Если они будут определены в разных исходных файлах, порядок их инициализации будет неуказан («»).

0
#include <iostream> 

class Foo { 
public: 
    static Foo *singleton() 
    { 
    if (foo == NULL) 
     foo = new Foo; 
    return foo; 
    } 
private: 
    Foo() 
    { 
    std::cout << "Foo()\n"; 
    } 
    static Foo *foo; 
}; 

Foo *Foo::foo = NULL; 

Foo *singleton = Foo::singleton(); 

int 
main() 
{ 
    std::cout << "main()\n"; 
    return 0; 
} 

Выход:

Foo() 
main() 
0

В двух словах:

// smooth.cpp 
#include "foo.h" 
#include "bar.h" 

Foo* Foo::singleton = new Foo(); 
Bar* Bar::singleton = new Bar(); 

Хороший синтаксис, чтобы избежать беспокоиться о том, что:

Foo& Foo::singleton() 
{ 
    static Foo Singleton; 
    return Singleton; 
} 

Хорошая вещь об этом синтаксисе, является то, что синглтон инициализируется при первом вызове метод, поэтому вам не придется беспокоиться (обычно), когда это происходит, поскольку при вызове метода для его доступа вы получаете его в любом случае :)

Смежные вопросы