resueltos - funciones de cadenas de caracteres en c++
¿Cuándo se debería usar std:: string en las matrices de caracteres? (7)
Bueno, volvería a formular tu pregunta un poco. Debería preguntar cuándo se debe usar la matriz de caracteres en lugar de std::string
.
Es porque siempre debe usar una string
menos que no pueda usarla. Por lo tanto, las situaciones en las que debe usar caracteres array en lugar de string
:
- El uso de API que admite
C
por lo que no puede utilizar lastring
. - Pasar datos entre
exe
ydll
. No se recomienda intercambiar tipos de datos que tengan constructor y / o destructor entreexe
ydll
Si te preocupa el rendimiento, después de la compilación con todas las optimizaciones habilitadas, la string
vuelve similar a la matriz de caracteres, quizás ofrezca un rendimiento aún mejor en algunos casos, por ejemplo, si necesitas obtener el número de caracteres que contiene.
También sobre el rendimiento, siempre puede pasar por referencia, como otras respuestas mencionadas, en caso de que tenga que pasar un puntero a la matriz de caracteres, puede usar el método c_str()
que devuelve const
puntero al primer carácter, si tiene que pasar el puntero ( no const
pointer) puede (pero no debería) pasarlo así: &str[0]
.
Me siento y pienso si debo usar o no const char*
o const std::string&
muy a menudo cuando estoy diseñando interfaces de clase y cuando se trata de eso, a menudo siento que hay 6 en una mano con la mitad una docena en el otro.
Tome los siguientes dos prototipos de funciones:
void foo(const char* str);
void foo(std::string str);
Si la función foo
fuera a almacenar una cadena, diría que la segunda es una mejor opción debido a la capacidad de pasar una cadena y utilizar la semántica de movimiento cuando sea posible. Sin embargo, si foo
solo necesitara leer la cadena, ¿sería mejor la solución const char*
?
En una perspectiva de rendimiento, no se necesitaría crear una std::string
temporal. Sin embargo, llamar a la función con una cadena ya existente como argumento se ve molesta: foo(mystr.c_str())
. Peor aún, si es necesario realizar operaciones más avanzadas en la matriz en algún momento de la carretera o si se debe almacenar una copia, la interfaz debe cambiar.
Entonces mi pregunta es esta:
¿Existen convenciones bien definidas, ya sean personales o de otro tipo, que rigen cuándo std::string
o const char*
es una mejor opción? Además, al comenzar un nuevo proyecto, ¿es mejor ser coherente con el uso o simplemente tomar el que mejor se adapte al fragmento actual de código?
En lugar de usar
void foo(std::string str);
podrías usar
void foo(const std::string& str);
que sería equivalente a
void foo(const char* str);
en términos de uso, porque no se asigna memoria al pasar una referencia. Pero para cadenas en C ++ definitivamente usaría std::string
. Para datos aleatorios o interfaces compatibles con C, no lo haría.
Si desea un mejor manejo de sus datos de opinión (en su caso será una cadena), diría que vaya con char *. Le dará un mejor acceso a su cadena de caracteres y a la utilización de la memoria. Pero si no tiene que preocuparse por el rendimiento y el problema de administración de la memoria, puede usar std :: string fácilmente.
Solo unas pocas notas de la experiencia personal. Si está trabajando en un proyecto de C ++ (según la etiqueta que ha agregado), cúmplase con la std::string
proporcionada tanto como pueda. No trates de reinventar la más básica de todas las estructuras, la cadena todopoderosa. Vi varios proyectos en los que reinventaron la cuerda básica y luego pasaron meses afinandola.
En el caso de su proyecto de C ++ desde el momento en que introdujo una variable char*
, strlen()
a las funciones C estándar, como strlen()
y strcpy
(solo para nombrar dos ...). Y a partir de este punto, su proyecto comienza a convertirse en un desastre, con asignación de memoria administrada a mano, etc.
En caso de que necesite interactuar con bibliotecas de terceros que acepten const char*
como su parámetro (y supongo que usted confía en esas bibliotecas, es decir: confía en que no const_cast
lejos la constness para hacer cosas malas con su cadena de pobres) puede utilizar std::string::c_str()
para obtener el const char*
fuera de su cadena.
En caso de que necesite interactuar con bibliotecas que tengan métodos que acepten char*
le recomiendo que tome una copia del c_str()
de su cadena y la use como parámetro de entrada en la biblioteca (por supuesto, no olvide eliminar la copia adicional) .
Además de estos puntos extra, me suscribo a los tres puntos de la respuesta de Angew.
std :: string es mejor que usar raw char * donde tienes que administrar asignaciones, desasignaciones y problemas relacionados con el tamaño para tener cuidado con cualquier overflow, underflow, que no estés cruzando el límite de tamaño. Mientras que std :: string estos son todos cuidados por abstracción
const char*
es un retroceso a C. Diría que en C ++ decente, el único uso para él es en las API extern "C"
.
std::string
tiene una serie de ventajas:
Proporciona una función de
size()
constantesize()
. Descubrir la longitud de unconst char*
requiere tiempo lineal.Se garantiza que es válido. Se debe verificar que un
const char*
sea nulo, y es posible pasar datos incorrectos, datos que faltan un terminador nulo. Semejante ocurrencia está garantizada que resultará en un bloqueo o algo peor.Es compatible con algoritmos estándar.
Si le preocupan los impactos en el rendimiento de tener que crear una std::string
para llamar a la función, considere tomar el enfoque que usa la biblioteca estándar; cambie la función para tomar un par de iteradores. A continuación, puede proporcionar una sobrecarga de conveniencia tomando const std::string&
delegando en el par de iteradores.
std::string
siempre debe ser la primera opción en c ++. Para evitar una sobrecarga de copia adicional, casi siempre se debe pasar el argumento como referencia y referencia siempre que sea posible.
En ese caso, la firma de tu función sería como esta
void foo (std :: string & str);
y así si el argumento es const
void foo (const std :: string & str);
Hay beneficios de esta palabra clave const que puedes mirar here