7
votes

Pourquoi les nouvelles fonctions C ++ 11 chaînes (STOD, STOF) ne sont-elles pas membres de la classe de cordes?

Pourquoi ces nouvelles fonctions C ++ 11 de l'en-tête ( stod , stof , stoull ) Fonctions de membre non membres de la chaîne classe

n'est pas plus conforme au C ++ pour écrire mystring.stod (...) plutôt que stod (mystring, ...) ?


4 commentaires

Ils n'ont pas besoin d'être, et std :: string a déjà beaucoup trop de fonctions membres. Voir le Monolithes "Unsgrong" Gotw .


Il aurait été bien si stod était un modèle qui pourrait prendre toute séquence objet au lieu de std :: string


std :: string est déjà un Monolith d'une classe , il n'a pas besoin de plus Fonctions membres.


Il y avait un comité de normalisation qui décidait de cela, alors demander que "plus compatible C ++" devrait sonner une cloche d'avertissement que le point de vue ici pourrait ne pas être le meilleur


3 Réponses :


22
votes

C'est une surprise pour beaucoup, mais c ++ est pas une langue orientée objet (contrairement à Java ou C #).

C ++ est une langue multi-paradigme et tente donc d'utiliser le meilleur outil pour le travail chaque fois que possible. Dans ce cas, un fonction libre est le bon outil.

ligne directrice : préférez les fonctions non membres non-amis aux fonctions des membres (à partir d'efficacité C ++, point 23)

raison : une fonction de membre ou une fonction d'ami a accès aux internes de la classe alors qu'une fonction non membre non-ami ne le fait pas; Par conséquent, utiliser une fonction non-membre non-ami augmente l'encapsulation .

exception : quand une fonction de membre ou une fonction d'ami fournit un avantage significatif (telle que la performance), elle vaut la peine d'être envisagée malgré le couplage supplémentaire. Par exemple, même si std :: Trouver fonctionne vraiment bien, des conteneurs associatifs tels que std :: set Fournissez une fonction de membre std :: Set :: Trouver < / code> qui fonctionne dans O (log n) au lieu de O (n).


6 commentaires

Si cette ligne directrice aurait juste été appliquée un peu plus tôt à std :: basique_string ...


@PMR: oui, std :: basic_string et tous les flux IO sont des dinosaures qui ont pré-existé la normalisation; En fait, la version originale de chaîne était entièrement définie en termes d'indices et lors du processus de normalisation, toutes les surcharges d'itérateurs ont été ajoutées pour en faire une séquence ... mais les anciennes méthodes ont été conservées pour la compatibilité .


Que se passe-t-il si le fonctionnement des fonctions mondiales non membres non-amis repose sur des membres privés de données de la classe?


@ 0x499602D2: Ce n'est pas possible par la construction, car le principe même d'une fonction non-membre non-amis n'a pas seulement accès à l'interface .


@Matthieuum. Cela implique donc que nous devrions mettre en œuvre des getters et des setters?


@ 0x499602D2: J'ai peur de ne pas être, du tout à suivre votre file de raisonnement. Je n'ai jamais rien dit sur les getters and Setters ... Si vous souhaitez mettre en œuvre une méthode absolument nécessite un accès aux internes de la classe, alors évidemment il sera mis en œuvre comme un membre fonction ou une fonction d'ami; Il n'y a pas de débat ici. La ligne directrice s'applique lorsque vous avez le choix , et plus souvent que pas Vous avez le choix, vous devez simplement prendre votre compte pour le réaliser. Quand tu ne le fais pas, tu ne le fais pas.



1
votes

En réalité, ils sont des fonctions utilitaires et ils n'ont pas besoin d'être à l'intérieur de la classe principale. Des fonctions utilitaires similaires telles que ATOI, ATOF sont définies (mais pour CHAR *) à l'intérieur de STDLIB.H et elles aussi sont des fonctions autonomes.


0 commentaires

3
votes

La raison fondamentale est qu'elles n'appartiennent pas. Ils N'a pas vraiment rien à voir avec des chaînes. Arrêtez-vous et réfléchissez à propos de ça. Les types définis par l'utilisateur doivent suivre les mêmes règles que types intégrés, donc chaque fois que vous avez défini un nouveau type d'utilisateur, Vous devriez ajouter une fonction à std :: string . Cela serait effectivement être possible en C ++: si std :: string avait un membre Modèle de fonction à , sans une implémentation générique, vous pourrait ajouter une spécialisation pour chaque type et appeler str.to () ou str.to () . Mais est-ce vraiment ce que tu veux. Cela ne semble pas être une solution propre pour moi, Avoir tout le monde écrit une nouvelle classe devoir ajouter une spécialisation à std :: string . Mettre ces choses dans la classe de string se bâtist, et c'est vraiment le contraire de ce que OO essaie d'atteindre.

si vous deviez insister sur Pure OO, ils devraient être membres de double , int , etc. (un constructeur, vraiment. Ceci est ce que Python fait, par exemple.) C ++ n'a pas insisté sur pure Oo, et n'autorise pas les types de base tels que double et int à avoir des membres ou des constructeurs spéciaux. Les fonctions libres sont donc à la fois une solution acceptable et la seule solution propre possible dans le contexte de la langue.

FWIW: Les conversions vers / depuis la représentation textuelle sont toujours un problème délicat: si je le fais dans le type cible, alors j'ai introduit une dépendance sur les différentes sources et éviers de texte dans le type cible --- et ceux-ci peuvent varier dans le temps. Si je le fais dans le type source ou évier, je les fais dépendant du type être converti, ce qui est encore pire. La solution C ++ est de Définir un protocole (dans std :: streambuf ), où l'utilisateur écrit une nouvelle fonction libre ( opérateur <<< / code> et opérateur >> ) pour gérer les conversions et comptent sur la résolution de surcharge de l'opérateur vers trouver la bonne fonction. L'avantage de la fonction libre solution est que les conversions ne font partie de ni les données type (qui n'a donc pas à connaître les sources et les puits) ni le type source ou évier (qui n'a donc pas à savoir sur Types de données définis par l'utilisateur). Il semble que la meilleure solution à moi. Et fonctionne comme stod ne sont que des fonctions de commodité, qui rendent une utilisation particulièrement fréquente plus facile à écrire.


0 commentaires