2012-07-19 15 views
26

¿Cómo se importa si mi código C++ (como se muestra más abajo) tiene una cadena inicializada como una cadena vacía:cadenas de inicialización como nulo vs cadena vacía

std::string myStr = ""; 
....some code to optionally populate 'myStr'... 
if (myStr != "") { 
    // do something 
} 

vs no/inicialización nulo:

std::string myStr; 
....some code to optionally populate 'myStr'... 
if (myStr != NULL) { 
    // do something 
} 

¿Existen mejores prácticas o errores al respecto?

+9

'NULL' (conceptualmente) es un puntero y solo debe utilizarse como tal. Un 'std :: string' no es un puntero, por lo que no debe combinarse. PD. las inicializaciones son las mismas: el ctor de 'std :: string' lo establece en la cadena vacía. – MSalters

+0

@MSalters hola Estoy de acuerdo con su punto, pero si los tipos parecen ser incompatibles, ¿por qué el compilador no arroja un error? Tengo VS 2010 y silenciosamente inicializa std :: string con NULL. –

+1

@Surfing_SO: Hay un constructor de cadenas que toma un puntero a una matriz de caracteres, terminada por un carácter cero ... incorrectamente no pasó ese puntero (NULL no apunta a una matriz de caracteres, ni a ninguna otra cosa). Esto es un comportamiento indefinido y cualquier cosa puede suceder en ese caso. – MSalters

Respuesta

48

Hay una función empty() listo para que en std::string:

std::string a; 
if(a.empty()) 
{ 
    //do stuff. You will enter this block if the string is declared like this 
} 

o

std::string a; 
if(!a.empty()) 
{ 
    //You will not enter this block now 
} 
a = "42"; 
if(!a.empty()) 
{ 
    //And now you will enter this block. 
} 
+5

'42' es la respuesta de todo. Lo hiciste bien –

2

yo prefere

if (!myStr.empty()) 
{ 
    //do something 
} 

También usted no tiene que escribir std::string a = "";. Puede acaba de escribir std::string a; - será vacía por defecto

17

No hay trampas. La construcción predeterminada de std::string es "". Pero no puede comparar una cadena al NULL. Lo más cerca que se puede obtener es comprobar si la cadena está vacía o no, usando el método std::string::empty ..

+0

Hay extra temporal cuando construyes 'std :: string' y le asigna' "" '. – vladon

+0

@vladon No estoy muy seguro de a qué temporal se refiere, o cómo la asignación es relevante. No puedo ver un temporal en 'a =" ";' cuando 'a' es' std :: string', pero la pregunta no es sobre eso. – juanchopanza

10

Mejor:

std::string subCondition; 

Esto crea una cadena vacía.

Este:

std::string myStr = ""; 

hace una copia de inicialización - crea una cadena temporal de "", y luego utiliza el constructor de copia para crear myStr.

Bono:

std::string myStr(""); 

hace una inicialización directa y utiliza el constructor string(const char*).

Para comprobar si una cadena está vacía, simplemente use empty().

+0

no 'std :: string myStr =" ";' invocar un constructor 'string (const char *)'? ¿Por qué crees que se creará un temporal? – Andrew

+0

@Andrew raro, ¿verdad? http://stackoverflow.com/questions/11223285/whats-the-motivation-between-having-copy-and-direct-initialization-behave-diffe –

+0

+1 para el enlace) – Andrew

1

El constructor predeterminado inicializa la cadena en la cadena vacía. Esta es la forma más económica de decir lo mismo.

Sin embargo, la comparación con NULL apesta. Esa es una sintaxis más antigua que todavía es de uso común y que significa algo más; un puntero nulo Significa que no hay una cuerda alrededor.

Si desea comprobar si una cadena (que no existe) está vacía, utilice el método empty lugar:

if (myStr.empty()) ... 
5

vacío-dad y "NULL-dad" son dos conceptos diferentes. Como otros mencionaron, el primero se puede lograr a través del std::string::empty(), este último se puede lograr con boost::optional<std::string>, p.:

boost::optional<string> myStr; 
if (myStr) { // myStr != NULL 
    // ... 
} 
Cuestiones relacionadas