2015-10-28 26 views
5

So che staticconstclass i membri possono essere inizializzati solo nelle intestazioni. È lo stesso per gli spazi dei nomi? Ad esempio, è valida per scrivere:variabile globale const nel namespace

namehuman.hpp

namespace namehuman 
{ 
    string const human("human"); 
} 

main.cpp

#include "namehuman.hpp" 
cout << namehuman::human << endl; 

Mi chiedo se tutti i file, tra cui il file di intestazione avrà la propria copia del string umano, o se l'umano sarà una vera variabile globale (non copiata molte volte). Per evitare che ognuno includa il file che ne fa la copia, sono obbligato a utilizzare extern?

risposta

4

Le costanti hanno un collegamento interno. Pertanto, qualsiasi unità di compilazione che include l'intestazione con la definizione della costante avrà una propria istanza dell'oggetto.

Secondo il C++ standard (3.5 Programma e linkage)

3 Un nome di dover ambito dello spazio dei nomi (3.3.6) ha il collegamento interno se è il nome di

.. .

- una variabile non volatile che viene dichiarato in modo esplicito const o constexpr e né esplicitamente dichiarato extern né in precedenza dichiarato di avere un collegamento esterno; oppure

Se si desidera una costante con collegamento esterno, è necessario dichiararla con l'identificatore extern e definirla in un'unità di compilazione.

1

Penso che definirò lo human diverse volte, quindi può succedere che ciò causi una violazione ODR (vedi sotto). Di solito è meglio a dichiarare solo nell'intestazione

extern const string human; 

e aggiungere la definizione al file di implementazione

string human("human"); 

attenzione circa il fiasco ordine di inizializzazione e l'equivalente quando si chiude l'applicazione.

È possibile che si verifichi una violazione ODR quando una funzione in linea con collegamento esterno utilizza ODR human. Penso che, dal momento che è davvero facile da fare e non c'è modo di proteggerlo, è meglio definire stringhe costanti nel file di implementazione.

+0

Perché il voto negativo? – Florian

+0

Anche se 'human' verrà definito più volte, non si tratta di una violazione ODR poiché le definizioni hanno un collegamento interno. La tua modifica suggerita, non è chiaro se si tratti di un miglioramento o meno, e potrebbe addirittura rallentare il codice; oltre a introdurre fiasco dove prima non c'era nessuno. –

+0

@Florian, perché mentre il tuo codice "funziona", è una risposta sbagliata (a proposito, non ho fatto downvote). Vedi l'altra risposta. – GreatAndPowerfulOz