Pourquoi ces nouvelles fonctions C ++ 11 de l'en-tête n'est pas plus conforme au C ++ pour écrire
stod code>,
stof code>,
stoull code >) Fonctions de membre non membres de la chaîne code> classe code> p>
mystring.stod (...) code> plutôt que
stod (mystring, ...) code>? P>
3 Réponses :
C'est une surprise pour beaucoup, mais c ++ est pas em> une langue orientée objet (contrairement à Java ou C #). P>
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 em> est le bon outil. P>
std :: Trouver code> fonctionne vraiment bien, des conteneurs associatifs tels que
std :: set code> Fournissez une fonction de membre
std :: Set :: Trouver < / code> qui fonctionne dans O (log n) au lieu de O (n). p>
Si cette ligne directrice aurait juste été appliquée un peu plus tôt à std :: basique_string code> ...
@PMR: oui, std :: basic_string code> et tous les flux IO sont des dinosaures qui ont pré-existé la normalisation; En fait, la version originale de code> chaîne code> é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 code> code>.
@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 i> nécessite un accès aux internes de la classe, alors évidemment i> 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 i>, et plus souvent que pas i> 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.
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. P>
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 à si em> vous deviez insister sur Pure OO, ils devraient être
membres de 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 :: string code>. Cela serait
effectivement être possible en C ++: si
std :: string code> avait un membre
Modèle de fonction
à code>, sans une implémentation générique, vous
pourrait ajouter une spécialisation pour chaque type et appeler
str.to
str.to
std :: string code>. Mettre ces choses
dans la classe de string se bâtist, et c'est vraiment le contraire
de ce que OO essaie d'atteindre. p>
double code>,
int code>, 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 code> et
int code> à
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. P>
std :: streambuf code>), où l'utilisateur écrit
une nouvelle fonction libre (
opérateur <<< / code> et
opérateur >> code>) 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 code> ne sont que des fonctions de commodité,
qui rendent une utilisation particulièrement fréquente plus facile à écrire. p>
Ils n'ont pas besoin d'être, et
std :: string code> a déjà beaucoup trop de fonctions membres. Voir le Monolithes "Unsgrong" Gotw .
Il aurait été bien si
stod code> était un modèle qui pourrait prendre toute séquence code> objet code> au lieu de
std :: string code>
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