33 votes

Quand doit-std::string être utilisé sur des tableaux de caractères?

Je s'asseoir et réfléchir pour savoir si ou non je dois être l'aide d' const char* ou const std::string& assez souvent quand je suis à la conception d'interfaces de classes, et quand il descend à lui, j'ai souvent envie de il y a 6 dans une main avec une demi-douzaine de l'autre.

Prendre la suite de deux prototypes de fonction:

void foo(const char* str);
void foo(std::string str);

Si l' foo fonction de stocker une chaîne de caractères, je dirais que la deuxième est une meilleure option en raison de la capacité de passer d'une chaîne et d'utiliser la sémantique de déplacement, lorsque cela est possible. Toutefois, si foo seulement nécessaires à la lecture de la chaîne, l' const char* solution de mieux?

Sur un point de vue performances, temporaire std::string n'auraient pas besoin d'être créé. Toutefois, l'appel de la fonction avec une chaîne comme argument regards insistants: foo(mystr.c_str()). Pire encore, si des opérations plus avancées doivent être faites sur le tableau à un certain point bas de la route ou si une copie doit être stocké, l'interface doit alors changer.

Donc ma questions est:est-ce

Existe-il bien défini, que ce soit personnel ou non, les conventions que la règle lors de l' std::string ou const char* est un meilleur choix? En outre, lors du démarrage d'un nouveau projet, est-il préférable d'être en accord avec l'usage ou il suffit de prendre celui qui correspond à l'actuel morceau de code de meilleur?

53voto

Angew Points 53063

const char* est un retour à la C. je dirais que décent, C++, à propos de l'utiliser car c'est en extern "C" Api.

std::string a un certain nombre d'avantages:

  1. Il fournit une constante de temps size() fonction. La découverte de la longueur d'un const char* prend le temps linéaire.

  2. Il est garanti pour être valide. Un const char* doit être vérifié pour être nulle, et il est tout à fait possible de passer des données incorrectes données manquantes d'un terminateur null. Un tel événement est presque garanti pour provoquer un accident ou pour le pire.

  3. Il est compatible avec les algorithmes standard.

Si vous êtes inquiet au sujet des effets sur les performances de devoir créer une std::string pour appeler la fonction, envisager de prendre de l'approche de la bibliothèque standard utilise - changement de la fonction de prendre une paire d'itérateurs à la place. Vous pouvez ensuite fournir une commodité de surcharge de prendre un const std::string& de déléguer à l'itérateur-paire.

21voto

fritzone Points 9925

Quelques notes à partir de l'expérience personnelle. Si vous travaillez sur un projet c++ (comme pour la balise que vous avez ajouté) coller à l' std::string fourni autant que vous le pouvez. Ne pas essayer de réinventer la plus fondamentale de toutes les structures, le tout-puissant de la chaîne. J'ai vu plusieurs projets où ils ont réinventé la chaîne de base et par la suite passé des mois à peaufiner cela.

Dans le cas de votre projet c++ à partir du moment où vous avez introduit un char* variable vous tomber en arrière à la norme C fonctions, telles que l' strlen() et strcpy (pour n'en citer que deux ...). Et de ce point votre projet commence à tourner dans un gâchis, avec la main géré l'allocation de la mémoire, etc...

Dans le cas où vous avez besoin d'interagir avec des bibliothèques tierces qui acceptent const char* que leurs paramètres (et je suppose que vous faites confiance à ces bibliothèques - ie: vous confiance, ils n' const_cast loin le constness à faire de mauvaises choses avec votre mauvaise chaîne de caractères), vous pouvez utiliser std::string::c_str() pour obtenir le const char* de votre chaîne.

Dans le cas où vous avez besoin d'interagir avec les bibliothèques qui ont des méthodes acceptant char* , je vous recommande fortement de prendre une copie de votre chaîne de l' c_str() et de l'utiliser comme paramètre entrant à la bibliothèque (bien sûr, ne pas oublier de supprimer la copie supplémentaire).

À côté de ces points supplémentaires, je viens de souscrire à toutes les trois points de Angew de réponse.

6voto

Abhishek Bansal Points 1166

std::string devrait toujours être le premier choix en c++. Pour éviter copie supplémentaire frais généraux, vous devriez presque toujours passer argument de référence et d' const de référence où et quand cela est possible.

Dans ce cas, votre fonction signature de devenir comme ça

void foo(std::string &str);

et comme ça si l'argument est const

void foo(const std::string &str);

Il y a des avantages de cette const mot-clé que vous pouvez regarder ici

4voto

Debasish Jana Points 1051

std::string est mieux qu'à l'aide de matières char * où vous devez gérer les affectations, deallocations et de taille lié à la question de d'être prudent pour toute dépassement de, dépassement de capacité, que vous ne traversent pas la limite de taille. Alors que std::string ce sont tous pris en charge par anstraction

4voto

Theolodis Points 3059

Au lieu d'utiliser

void foo(std::string str); 

vous pouvez utiliser

void foo(const std::string& str);

ce qui serait équivalent à

void foo(const char* str);

en termes d'usage, parce que personne ne la mémoire est allouée lors du passage d'une référence. Mais pour les chaînes de caractères en C++, je serais certainement utiliser std::string. Pour des données aléatoires ou C des interfaces compatibles je ne le ferais pas.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X