2010-01-20 3 views

Répondre

8

Pour les littéraux de chaîne, et uniquement pour les constantes de chaîne provenant de littéraux, j'utiliserais const char[]. L'avantage principal de std::string est qu'il a la gestion de la mémoire gratuitement, mais ce n'est pas un problème avec les littéraux de chaîne. De toute façon, il s'agit du type réel du littéral, et il peut être directement utilisé dans n'importe quelle API qui requiert les anciennes chaînes terminées par le style C ou les chaînes C++ (conversion implicite). Vous obtenez également une implémentation de la taille du temps de compilation en utilisant le tableau au lieu du pointeur. Maintenant, lors de la définition des interfaces de fonction, et même si les constantes sont censées être transmises, je préférerais std::string plutôt que const char*, car dans ce dernier cas la taille est perdue, et devra éventuellement être recalculée.

De ma propre expérience. J'ai vieilli de l'écriture .c_str() sur chaque appel à la bibliothèque de journalisation (qui utilisait des arguments variables) pour les chaînes littérales avec des messages d'info/erreur.

2

Vous devez utiliser ce qui est plus approprié pour vous. Si aucune exigence particulière je utiliserais std::string parce qu'il fait tout le travail de mémoire.

Pour les littéraux de chaîne, j'utiliserais const char*. La raison contre const char[] est que vous pouvez utiliser const char* pour initialiser une autre constante. Vérifier le code suivant:

const char str1[] = "str1"; 
const char* str11 = "str11"; 

const char str2[] = str1; // <<< compile error 
const char* str22 = str11; // <<< OK 

littéraux de chaîne a une durée de stockage statique (selon 2.13.4/2), de sorte pointeur const char* sera valable jusqu'à la fin du programme.

+0

Et il est plus rapide dans de nombreuses implémentations STL grâce à un mécanisme de copie sur écriture si vous utilisez les mêmes chaînes dans de nombreux endroits différents, ce qui le rend également plus facile à utiliser que les chaînes C simples. A côté de cela, si vous avez besoin de supporter plusieurs langues, je préfère utiliser std :: wstring. – jdehaan

+0

@jdehaan: Je serais surpris s'il y a (m) des implémentations de bibliothèques std (pas des implémentations STL, car 'std :: string' ne faisait pas partie de la STL) qui fait encore COW. Dans les environnements MT, cela se transforme généralement en une pessimisation. Je pense que l'optimisation des petites chaînes (les petites chaînes ne sont pas allouées sur le tas, mais sur la pile) est ce qui est généralement préféré maintenant. – sbi

+0

La copie à l'écriture est supprimée (si elle est toujours présente) dans la plupart des implémentations. Il a des problèmes dans les environnements multithread, car certaines opérations qui semblent thread-safe du point de vue de l'utilisateur (ils se réfèrent à différentes chaînes std :: string) peuvent ne pas être thread-safe. Considérez une chaîne copiée avec chaque copie passée sur différents threads pour la modification. Chaque thread a sa propre chaîne, aucun objet partagé, mais en fait il peut y avoir une condition de concurrence dans l'implémentation interne 'copy-on-write'. L'ajout d'un mécanisme de verrouillage dans la bibliothèque le rend plus lent qu'une simple implémentation dans de nombreux cas. –

2

Que faites-vous avec cela? Qu'attendent vos méthodes? Const est plus léger dans le stockage, mais n'a pas la puissance de std :: string, ou la sécurité lors de son utilisation. Cependant, si vous avez beaucoup d'API C, c'est peut-être le choix le plus judicieux. Std :: string serait l'option préférée.

+2

.c_str() est votre ami :) – JPvdMerwe

+0

@JPvdMerwe: theatrus est correct. Si tout ce que vous faites est de passer une chaîne constante à des fonctions nécessitant un 'const char *', il est inutile d'utiliser 'std :: string' /' .c_str() '. Un tableau 'const' de' char' n'a pas de coût d'appel de constructeur et peut être transmis directement aux fonctions, ce qui le rend moins cher à construire et moins coûteux à transmettre aux fonctions qu'un 'std :: string'. –

+0

Oui pour les littéraux de chaîne, je suis tout à fait d'accord, aucun point ne gâche le temps de votre processeur. – JPvdMerwe

1

J'ai tendance à préférer const std::string sur const char * pour les littéraux de chaîne. Parce que le passage de littéraux de chaîne dans des fonctions prenant const std::string & créera silencieusement une chaîne chaque fois qu'ils seront appelés au lieu d'un seul. Cependant, si j'utilise principalement le littéral avec des fonctions qui attendent un const char *, je l'utiliserai à la place.

Je tends à favoriser std::string pour l'apis. Bien sûr, si j'utilise unicode, j'utilise std::wstring et wchar_t.

+0

J'ai fait la même hypothèse à propos de l'Unicode, mais c'est intéressant: http://utf8everywhere.org/. Il s'avère que wchar_t est quelque chose d'une relique d'un temps plus simple dans l'histoire d'unicode, car l'API Win32 est native de WCHAR. La vie peut être meilleure si vous vous en tenez à UTF-8 et std :: string. – terriblememory