146 votes

But de retourner par valeur const?

Quel est le but de la const-t-il?

const Object myFunc(){
    return myObject;
}

Je viens de commencer la lecture Effective C++ et de l'Article 3 de défenseurs de la ce et d'une recherche sur Google ramasse des suggestions similaires, mais aussi des contre-exemples. Je ne vois pas comment l'utilisation de const ici serait préférable. En supposant un retour par valeur est souhaitable, je ne vois pas de raison de protéger la valeur retournée. L'exemple donné pour pourquoi il peut être utile, c'est de prévenir involontaire bool jette de la valeur de retour. Le problème réel est alors qu'implicite bool jette devraient être évités avec le mot clé explicit.

À l'aide de const ici empêche à l'aide d'objets temporaires sans affectation. Donc je ne pouvais pas effectuer des expressions arithmétiques avec ces objets. Il ne semble pas comme il y a un cas ou l'une sans nom const est utile.

Ce qui est gagné par l'utilisation de const ici et quand serait-il préférable?

EDIT: Changement de l'arithmétique exemple d'une fonction qui modifie un objet que vous pouvez effectuer avant une mission. (Ceci est mon premier post et wow, je ne peux pas croire à quelle vitesse les gens mettent ensemble les bonnes réponses, avec des exemples de code et des nids de liens, merci!)

144voto

Kerrek SB Points 194696

Dans la situation hypothétique où vous pourriez effectuer potentiellement coûteux non-const opération sur un objet, retour par le const valeur vous évite de l'appel de cette opération sur un temporaire. Imaginez qu' + a renvoyé un non-const valeur, et l'on peut écrire:

(a + b).expensive();

À l'âge de C++11, cependant, il est fortement conseillé de retourner des valeurs comme la non-const de sorte que vous pouvez profiter pleinement de références rvalue, qui n'ont de sens que sur la non-constante rvalues.

En résumé, il est une justification de cette pratique, mais c'est essentiellement obsolètes.

51voto

Il est assez inutile de revenir un const de la valeur à partir d'une fonction.

Il est difficile de l'obtenir pour avoir un effet sur votre code:

const int foo() {
   return 3;
}

int main() {
   int x = foo();  // copies happily
   x = 4;
}

et:

const int foo() {
   return 3;
}

int main() {
   foo() = 4;  // not valid anyway for built-in types
}

// error: lvalue required as left operand of assignment

Si vous pouvez remarquer que si le type de retour est un type défini par l'utilisateur:

struct T {};

const T foo() {
   return T();
}

int main() {
   foo() = T();
}

// error: passing ‘const T' as ‘this' argument of ‘T& T::operator=(const T&)' discards qualifiers

on peut se demander si ce n'est d'aucun bénéfice pour personne.

Renvoie une référence est différente, mais à moins d' Object est certain paramètre du modèle, vous n'êtes pas le faire.

8voto

Grizzly Points 11329

Il permet de s'assurer que le retour de l'objet (qui est une RValue à ce point) ne peut pas être modifié. Cela permet de s'assurer que l'utilisateur ne peut pas faire pense comme ceci:

myFunc() = Object(...);

Qui fonctionnerait bien si myFunc retournées par référence, mais il s'agit certainement d'un bug lors de son retour par valeur (et probablement de ne pas être pris par le compilateur). Bien sûr, en C++11 avec sa rvalues la présente convention ne pas faire comme beaucoup de sens, comme il l'a fait plus haut, depuis un const objet ne peut pas être déplacé, donc cela peut avoir assez lourd, les effets sur la performance.

1voto

Nicol Bolas Points 133791

C++11, c'est plutôt utile pour déplacer uniquement les objets. Par exemple:

const std::unique_ptr<T> myFunc();

unique_ptr est un type qui ne peut pas être copié; il ne peut être déplacé. Mais vous ne pouvez pas appeler std::move sur const type. Par conséquent, la seule façon de stocker, c'est avec une const& ou const&&:

const std::unique_ptr<T> &ptr = myFunc();

Puisque c'est un const unique_ptr, il ne peut pas être déplacé. Il ne peut être copié. Ce qui signifie qu'il est très difficile de stocker n'importe où à long terme. Vous pouvez le mettre sur la pile. Mais ce qui en fait un membre d'une classe est impossible (sans faire appel à un comportement indéfini).

De cette façon, on peut s'assurer que le pointeur ne pas se stocker à long terme. Cela permet de créer une version spécialisée d' unique_ptr qui deleter ne fait pas les supprimer de la mémoire. De cette façon, une fonction peut retourner un pointeur sachant que l'utilisateur ne peut pas le stocker n'importe où.

Bien sûr, cela fait aussi qu'il est assez difficile pour l'appelant pour retourner la valeur. Donc, il y a des inconvénients.

-3voto

Steven Feldman Points 477

Il pourrait être utilisé comme une fonction wrapper pour renvoyer une référence à un type de données constant privé. Par exemple, dans une liste chaînée, vous avez les constantes tail et head et si vous voulez déterminer si un nœud est un nœud tail ou head, vous pouvez le comparer à la valeur renvoyée par cette fonction.

Bien que tout optimiseur l’optimise probablement de toute façon ...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X