2011-09-27 14 views
11

Eventuali duplicati:
C++ static constant string (class member)
static const C++ class member initialized gives a duplicate symbol error when linkingCome definisco le costanti di stringa in C++?

La mia esperienza con C++ pre-datato l'aggiunta della classe string, quindi sto ricominciando in qualche modo.

Sto definendo il mio file di intestazione per la mia classe e voglio creare una costante statica per un URL. Sto tentando questo facendo come segue:

#include <string> 
class MainController{ 
private: 
    static const std::string SOME_URL; 
} 

const std::string MainController::SOME_URL = "www.google.com"; 

Ma questo mi dare una definizione duplicata durante il collegamento.

Come posso realizzare questo?

+0

dup. Http://stackoverflow.com/questions/2888805/static-const-c-class-member-initialized-gives-a-duplicate-symbol-error-when-lin –

risposta

10

Spostare il

const std::string MainController::SOME_URL = "www.google.com"; 

in un file cpp. Se lo hai in un'intestazione, allora ogni .cpp che lo include avrà una copia e otterrai l'errore di simbolo duplicato durante il collegamento.

+1

Immagino che quello che non capisco è che ho questi all'interno delle mie guardie. Questo ha risolto il problema, ma non capisco perché ... – Thom

+3

@Thom, il problema non è risolto con le protezioni delle intestazioni perché ogni unità di traduzione (file cpp) include l'intestazione in modo che ogni unità di traduzione finisca con una "copia" della stringa con lo stesso nome, il risultato è che ogni unità di traduzione è compilata correttamente. Tuttavia quando si collegano più unità di traduzione hanno lo stesso simbolo (la stringa) e questo provoca l'errore di collegamento dovuto al collegamento simbolico. –

2

È necessario inserire la definizione const std::string MainController::SOME_URL = "www.google.com"; in un singolo file di origine, non nell'intestazione.

2

Definire la classe nel file di intestazione:

//file.h 
class MainController{ 
private: 
    static const std::string SOME_URL; 
} 

E poi, nel file sorgente:

//file.cpp 
#include "file.h" 

const std::string MainController::SOME_URL = "www.google.com"; 
9

Hai bisogno di mettere la linea

const std::string MainController::SOME_URL = "www.google.com"; 

nel file cpp , non l'intestazione, a causa dello one-definition rule. E il fatto che non è possibile inizializzarlo direttamente nella classe è perché std::string non è un tipo integrale (come int).

In alternativa, a seconda del caso d'uso, si potrebbe considerare di non creare un membro statico ma utilizzare invece un namespace anonimo. See this post for pro/cons.

+0

Anche se è di tipo integrale, verrà dare errore Cioè, non ha NIENTE da fare con il * tipo * del membro statico; finché fornisci * definizione * del membro nell'intestazione, darà errore. – Nawaz

+1

@Nawaz In pratica. Formalmente, più definizioni nelle unità di traduzione delle differenze sono comportamenti indefiniti, quindi un compilatore potrebbe farlo funzionare. (O fare qualsiasi altra cosa, ma "farlo funzionare" era un'implementazione comune in C. Dove i costruttori non vi entravano.) –

+1

@JamesKanze: Che cosa stai cercando di dire? Che ha a che fare con * tipo * del membro statico? – Nawaz

Problemi correlati