7
votes

Opérateur Char * en classe de cordes STL

Pourquoi la classe STL String n'a-t-elle pas un opérateur de char * surchargé? Y a-t-il une raison spécifique à eux de l'éviter?

S'il y en avait un, alors que l'utilisation de la classe de cordes avec c fonctionne deviendrait beaucoup plus pratique.

J'aimerais connaître votre point de vue.


0 commentaires

6 Réponses :


12
votes

Vous devriez toujours éviter les opérateurs de moulage, car ils ont tendance à introduire des ambiguïtés dans votre code qui ne peuvent être résolus qu'avec l'utilisation de nouvelles coulées, ou pire encore, mais ne faites pas ce que vous attendez. Un opérateur Char * () aurait beaucoup de problèmes. Par exemple:

string s = "hello";
strcpy( s, "some more text" );


3 commentaires

donc, string s = "bonjour"; Strcpy (x, s.c_str ()); a deux opérations de copie?


Peut-être. La plupart des mises en œuvre STD :: String String classent réellement un terminateur null sur leur représentant interne, donc aucune copie n'est requise, mais la norme n'interdit pas une copie. La réponse à de tels problèmes, bien sûr, n'est pas d'utiliser Char *, Const ou autre, à l'exception des API héritées.


@Sahasranaman: Si vous jetez un coup d'œil à la réponse de Martin (String String Internal Data n'est pas nécessairement contiguë), vous verrez certains cas (implémentations STL possibles) pour lesquelles la copie est requise. Ensuite, il ne sera pas non plus en C ++ 0x lorsque la contiguïté est une exigence. Je ne connais aucune implémentation de STL où le stockage n'est pas contigu de toute façon, donc dans la vie réelle .C_STR () et .Data () renvoyer un pointeur dans le tampon interne sans copie.



5
votes

La spécification de modèle de chaîne permet délibérément une représentation "déconnectée" des chaînes, où l'ensemble du contenu de la chaîne est composé de multiples morceaux. Une telle représentation ne permet pas une conversion facile au caractère *.

Cependant, le modèle de chaîne fournit également la méthode C_STR pour précisément le but que vous souhaitez: Qu'est-ce qui ne va pas avec l'utilisation de cette méthode?


7 commentaires

Il n'y a rien de mal à utiliser c_str (), elle dit qu'il serait plus pratique s'il n'est pas nécessaire d'utiliser le C_STR () également.


Je pense que la mauvaise idée de 'Chunks' - C_STR permet une itération sur une chaîne entière sans lacunes.


Je ne suis pas d'accord avec vous. Avoir à penser à la distribution ici est une chose sage. Martin fournit une bonne explication pourquoi c'est le cas.


Mise en œuvre de la corde (c'est-à-dire à l'aide de plusieurs morceaux) améliore la performance insert / Supprimer - au moins en théorie. De plus, STD: itérateurs .string autorisent toujours l'itération "sans lacunes".


@SahasranaNan: ce n'est pas clair pour moi si l'OP est au courant de C_STR; Je trouverais qu'il est surprenant qu'un opérateur de char * soit décrit comme beaucoup plus pratique que c_str. @Dewfy: C'est précisément la raison de c_str. Si la chaîne est mise en œuvre avec une corde, C_STR devra la réorganiser. Il existe des contraintes spécifiques pour combien de temps le pointeur renvoyé par C_STR reste valide, il est donc utile que vous devez l'appeler explicitement - pour un opérateur de conversion implicite, vous ne pouvez pas savoir que vous n'êtes pas censé changer l'objet de chaîne.


@Martin: Il serait pratique d'utiliser, String S = "Bonjour"; Strcpy (x, s); au lieu de String S = "Bonjour"; Strcpy (x, s.c_str ()); . Il y a eu plusieurs situations pour moi aussi où j'ai dû utiliser des fonctions héritées pour atteindre l'inter-op avec le code plus ancien. Je ne trouve rien de mal à dire qu'un opérateur de char * surchargé est plus facile à utiliser que c_str lorsque vous traitez des fonctions C telles que Strcpy.


C ++ 0x mandatera le stockage contigu pour STD :: basic_string, mais ne fournira pas un opérateur de distribution au graphique *. Je pense que cela signifie que si votre argument fournit une affaire sonore pour laquelle l'API de chaîne actuelle ne peut appuyer confortablement à soutenir la conversion implicite, elle ne reflète pas le raisonnement du comité des normes.



2
votes

Vous pouvez utiliser c_str à la place:

string s("I like rice!");
const char* cstr = s.c_str();


0 commentaires

2
votes

En 1998-2002, il s'agissait d'un sujet brûlant des forums C ++. Le problème principal - zéro terminateur. Spécification de STD ::? String autorise le caractère zéro comme normal, mais char * string pas.


0 commentaires

16
votes

Voici la citation du livre de Josuttis STL:

Cependant, il n'y a pas de type automatique conversion d'un objet de chaîne à un C chaîne. Ceci est pour des raisons de sécurité Pour éviter les conversions de type non intentionnelles Cela entraîne un comportement étrange (type char * a souvent un comportement étrange) et ambiguïtés (par exemple, dans un expression qui combine une chaîne et une c-string, il serait possible de Convertir la chaîne en char * et vice versa). Au lieu de cela, il y en a plusieurs façons de créer ou d'écrire / copier dans un C-string, en particulier, c_str () est fourni pour générer la valeur d'un chaîne en c-string (comme personnage tableau qui a '\ 0' comme son dernier caractère).


1 commentaires

Là où je travaille, nous avons une bibliothèque héritée qui a une chaîne avec une conversion de type automatique sur Cons-Char *. Je ne peux pas compter nombre de fois que nous avons été mordu par des développeurs d'applications Ajout d'une chaîne et un entier en supposant qu'ils disposeront de la mise en forme et de la concaténation et de créer de très mauvaises choses ...



0
votes

Si vous avez besoin d'interoper avec des fonctions de style C, en utilisant un std :: vecteur / est souvent plus facile.

Ce n'est pas aussi pratique, et malheureusement que vous ne pouvez pas o (1) -swaper avec un std :: string (maintenant que serait une bonne chose) .

À cet égard, je préfère beaucoup l'interface de MFC / ATL CSTRing qui a des garanties de performances plus strictes, fournit une interoption, et ne traite pas les chaînes de caractère / unicode larges comme totalement étrangères (mais ok, Ce dernier est un peu spécifique à la plate-forme).


0 commentaires