Question

J'ai aller une question très simple, mais je ne peux malheureusement pas comprendre la réponse moi-même.

Supposons que j'ai une structure de données qui contient les paramètres et agit comme une carte des paramètres. J'ai un procédé de GetValue(const std::string& name), qui retourne la valeur correspondante.

Maintenant, je suis en train de comprendre - quel genre d'approche valeur de retour serait mieux. Les moyens évidents d'un acte faisant ma méthode comme

std::string GetValue(const std::string& name) const

et retourner une copie de l'objet et de compter sur RVO dans les significations de performance.

L'autre signifierait faire deux méthodes

std::string& GetValue(...)
const std::string& GetValue(...) const

ce qui signifie généralement dupliquer le code ou en utilisant des moulages de constantes de mal à utiliser l'une de ces routines deux fois.

#Q

Quel serait votre choix dans ce genre de situation et pourquoi?

Était-ce utile?

La solution

En fait, je voudrais probablement utiliser:

std::string GetValue(const std::string& name) const;
// or
const std::string* GetValue(const std::string& name) const;

void SetValue(std::string name, std::string value);

Setter premier:

  • Passage par valeur SetValue permet au compilateur certaines optimisations qui ne peuvent pas être faites avec passage par const-référence, il a été expliqué dans un article de Dave Abrahams, "voulez-vous Speed? passe par la valeur."
  • L'utilisation d'un Setter est généralement mieux, parce que vous pouvez vérifier la valeur étant fixée alors qu'avec une référence simple, vous avez aucune garantie que l'appelant ne faites rien de stupide avec les données.

Pour le getter:

  • De retour par copie semble être un gaspillage car la plupart du temps vous ne modifiera pas l'objet retourné (pour un paramètres de la carte), mais pointeur ou référence ne signifie pas que l'objet aliasé vivra assez longtemps, si vous ne pouvez pas garantir alors le point est sans objet: retour en termes de valeur. Aussi copie permet d'éviter d'exposer un détail interne, par exemple si vous étiez soudainement passer à std::wstring parce que vous avez besoin de paramètres en UTF-8 ...
  • Si vous avez besoin de performances, alors vous êtes prêt à faire des concessions dans ce département. Cependant, une référence ne vous permet pas de signaler l'absence de la propriété (sauf si vous avez une valeur magique) alors que le pointeur rend facile (NULL est déjà découpé pour vous).

Autres conseils

Cela dépend de l'utilisation. Devrait GetValue("foo") = "bar" sens? Dans ce cas, le retour en termes de valeur ne fait pas ce que vous voulez.

Si vous pouvez retourner par référence const, faites. La seule raison de retourner une classe gestion de la mémoire comme std :: string en valeur est parce qu'il est une chaîne temporaire.

Ceci est très "sensible" point de C ++. À mon humble avis, il est l'un des points les plus faibles de la conception C. Autant que je sache il n'y a pas vraiment bon choix, qui sera à la fois apparence et les performances bien.

Un point qui devrait être mentionné que l'optimisation RVO fait habituellement qu'une partie du travail. Sans une expression typique comme ceci:

std::string txt = GetValue("...");

produira en fait 2 copies! Cela dépend du compilateur, mais généralement optimisation RVO élimine juste une copie, mais l'autre est toujours là.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top