c++ - leer - constantes de cadena estáticas en clase vs espacio de nombres para constantes
leer cadenas con espacios en c (4)
Quiero declarar constantes de cadena que se usarán en varias clases del proyecto. Estoy considerando dos alternativas
Opción 1:
#header file
class constants{
static const string const1;
};
#cpp file
const string constants::const1="blah";
Opcion 2:
#header file
namespace constants{
static const string const1="blah";
};
Me preguntaba cuál sería una mejor implementación.
Ya mirado
Dónde almacenar las constantes con nombre específico de clase en C ++
Dónde poner cadenas constantes en C ++: miembros de clase estáticos o espacios de nombres anónimos
ACTUALIZAR:
Opción 3:
Con base en las sugerencias de "potatoswatter" y "sellibitze", ¿actualmente tengo la siguiente implementación?
#header file
namespace constants{
extern const string& const1(); //WORKS WITHOUT THE EXTERN ***WHY***
};
#cpp file
namespace constants{
const string& const1(){static string* str = new string ("blah"); return *str;}
}
Incluyo el archivo de encabezado donde necesito usar las constantes. ¿Hay algún inconveniente importante de esta implementación?
La Opción 1 logra lo mismo que la Opción 2, pero de una manera más desordenada.
Si va a utilizar una clase que solo tiene miembros estáticos, especialmente para las constantes / acceso global, use un espacio de nombres.
Ninguno. Yo iría con esto:
// header file
namespace constants {
extern const char const1[];
}
// cpp file
namespace constants {
extern const char const1[] = "blah";
}
El archivo de encabezado contiene una declaración de const1
con tipo incompleto pero convertible a char const*
y el archivo cpp contiene una definición de la matriz de caracteres con enlace externo. No hay una inicialización dinámica como la que tiene con std::string
. Entonces, eso es una ventaja, en mi humilde opinión.
Actualización 2 años después:
Cada global accesible por más de un archivo fuente debe estar envuelto en una función en inline
para que el vinculador comparta el objeto entre los archivos, y el programa lo inicialice correctamente.
inline std::string const &const1 {
static std::string ret = "hello, world!";
return ret;
}
La función en inline
es implícitamente extern
y puede envolverse en un espacio de nombres nombrado o una clase, si lo desea. (Pero no use una clase solo para contener miembros estáticos, ya que los espacios de nombres son mejores para eso. Y no use un espacio de nombres anónimo ya que eso vencería al enlazador, y cada fuente vería un objeto std::string
diferente).
Todas las respuestas que recurren a std::string
corren el riesgo de asignar dinámicamente memoria para un literal de cadena que se mantendrá constante durante toda la vida útil del programa (y el binario), por lo que deben evitarse.
La respuesta de sellibitze se acerca, pero tiene el problema de declararla una vez y luego definirla en otra parte, lo cual no me parece elegante y es más trabajo. La mejor manera sería
namespace constants {
const char * const blah = "blah!"
const char * const yada = "yada yada!"
}
Esta es la solución se analiza más aquí .