2011-09-24 7 views
5

Ho un vettore in un colpo di testa, in questo modo:Vettore globale che si svuota tra le chiamate?

extern std::vector<Foo> g_vector; 

Nel file cpp associato ho questo:

std::vector<Foo> g_vector; 

Ho anche una classe Bar, e in essa di costruttore si aggiunge alcune cose a g_vector, in questo modo:

Bar::Bar(/* stuff */) 
{ 
    // do things 
    std::cout << g_vector.size() << std::endl; 
    g_vector.push_back(somefoo); 
    std::cout << g_vector.size() << std::endl; 
} 

Se dichiaro una Bar all'interno di una funzione, come un sano persona, sembra funzionare bene. Tuttavia, se voglio dichiarare una Bar al di fuori di una funzione, cose strane accadono. Per esempio, ho un Bar dichiarata in MyFile1.cpp e in MyFile2.cpp, ea causa delle mie affermazioni cout a Bar posso vedere il Foo ottenere spinto nel vettore, ma quando il prossimo Bar corre il suo costruttore dimensione del vettore è 0 ancora. In altre parole, la mia uscita è

0 
1 
0 
1 

Cosa dà? Tanto per essere più sicuri doppia, ho anche provato a stampare &g_vector per assicurarsi che era in realtà push_back ing nel vettore a destra, e gli indirizzi di tutte le partite. Per quello che vale, non importa in quale ordine queste cose vanno nel vettore. Non mi interessa l'ordine di inizializzazione o altro.

+1

Avete qualche ragione di credere che il vostro 'g_vector' otterrà costruiti prima del vostro statico esempio' bar'? – Gabe

risposta

6

Non sono sicuro di quale sia il problema, ma suppongo che il seguente schema possa aiutare a risolverlo: definire un accessorio per la variabile globale e allocarlo come variabile di funzione statica come mostrato di seguito.

Nel file di intestazione:

std::vector<Foo> &getGlobalVector(); 

Nel file cpp:

std::vector<Foo> &getGlobalVector() 
{ 
    static std::vector<Foo> s_vector; 
    return s_vector; 
} 

Questo modello è ispirato dalla realizzazione "Singleton generico" di Andrei Alexandrescu in Design moderno C++.

Ho preso l'abitudine di utilizzare sistematicamente questo modello ogni volta che mi sono imbattuto in una variabile globale esistente pur mantenendo le applicazioni esistenti (o nelle rare occasioni in cui ho effettivamente scelto di usarne una anch'io), e potrebbe aver contribuito ad eliminare un un paio di bug difficili da riprodurre nelle suddette applicazioni.

In ogni caso, questo dovrebbe davvero aiutare a evitare qualsiasi problema di inizializzazione multipla o di ordine di inizializzazione.

6

ordine di inizializzazione dei valori globali non è definito.

Leggi qui circa il static initialization fiasco.

Quando si dichiara Bar in una funzione, lo g_vector verrà inizializzato prima, perché è stato promesso di essere inizializzato prima dell'esecuzione del programma. Se Bar è una variabile globale, allora hai un problema.

Problemi correlati