2011-09-27 11 views
11

Duplicar posibles:
C++ static constant string (class member)
static const C++ class member initialized gives a duplicate symbol error when linking¿Cómo se definen las constantes de cadena en C++?

Mi experiencia con C++ es anterior a la adición de la clase cadena, por lo que estoy empezando otra vez en algunos aspectos.

Estoy definiendo mi archivo de cabecera para mi clase y quiero crear una constante estática para una url. Estoy intentando hacer esto mediante la siguiente manera:

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

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

Pero esto me dará una definición duplicada durante el enlace.

¿Cómo puedo lograr esto?

+0

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

Respuesta

10

Mover el

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

a un archivo CPP. Si lo tiene en un encabezado, entonces cada .cpp que lo incluya tendrá una copia y obtendrá el error de símbolo duplicado durante el enlace.

+1

Supongo que lo que no entiendo es que tengo estos dentro de mis protectores de cabecera. Esto solucionó el problema, simplemente no entiendo por qué ... – Thom

+3

@Thom, el problema no se resuelve con los protectores de los encabezados porque cada unidad de traducción (archivo cpp) incluye el encabezado para que cada unidad de traducción termine con una 'copia' de la cadena con el mismo nombre, el resultado es que cada unidad de traducción compilada correctamente. Sin embargo, cuando se vinculan múltiples unidades de traducción tienen el mismo símbolo (la cadena) y eso provoca el error de enlace debido al enlace simbólico. –

2

Debe poner la definición const std::string MainController::SOME_URL = "www.google.com"; en un solo archivo fuente, no en el encabezado.

2

Definir la clase en el archivo de cabecera:

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

Y luego, en el archivo de origen:

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

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

Es necesario poner la línea

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

en el archivo CPP , no el encabezado, debido a one-definition rule. Y el hecho de que no pueda inicializarlo directamente en la clase es porque std::string no es un tipo integral (como int).

Alternativamente, dependiendo de su caso de uso, podría considerar no hacer un miembro estático sino usar un espacio de nombre anónimo. See this post for pro/cons.

+0

Incluso si es de tipo integral, lo hará dar error Es decir, no tiene NADA que ver con el * tipo * del miembro estático; siempre que proporcione * la definición * del miembro en el encabezado, dará error. – Nawaz

+1

@Nawaz En la práctica. Formalmente, las múltiples definiciones en las unidades de traducción de diferencia es un comportamiento indefinido, por lo que un compilador podría hacerlo funcionar. (O hacer cualquier otra cosa, pero "hacerlo funcionar" fue una implementación común en C. Donde los constructores no entraron.) –

+1

@JamesKanze: ¿Qué intentas decir? ¿Que tiene que ver con * type * del miembro estático? – Nawaz

Cuestiones relacionadas