6
votes

C ++ Références VS Valeurs de retour

Je comprends que le principe des références est d'éviter de faire des copies de grandes structures, mais si une fonction que vous écrivez crée une grande structure? Est-ce moins efficace (ou êtes-vous plus susceptible de manquer de mémoire) pour créer la variable localement, puis le renvoyer, que vous ne devez transmettre l'objet de destination comme référence et le remplir de la fonction?

i Je n'arrive pas à souligner cela, donc un exemple concret: Supposons qu'une fonction prend une chaîne et renvoie un vecteur de chaque ligne dans la chaîne. Existe-t-il un avantage matérielle à la fonction: xxx

sur: xxx

merci pour toute aide, Wyatt


2 commentaires

Je pense que vous manquez un & dans le premier extrait de code. ( out devrait être une référence ...)


Out est une référence ... Je suis désolé, il manquait, quelqu'un d'autre l'a modifiée.


4 Réponses :


6
votes

Cela dépend de si votre compilateur prend en charge optimisation de la valeur de retour (la plupart do) et si le code est admissible à cette optimisation.


2 commentaires

VC2005 effectue nommé RVO, qui vous sauve des maux de tête lors du retour du vecteur (afin que vous n'ayez pas à construire des itérateurs "paresseux" partout sur la place). Voir MSDN.MicRosoft.com/en-us/ Bibliothèque / MS364057 (v = vs.80) .aspx


Notez également que au moins un compilateur (VC ++) effectuera une ancienne RVO même lorsque toutes les optimisations sont désactivées .



1
votes

Eh bien, dans votre cas spécifique (remplissant un conteneur avec des valeurs) J'irais une approche d'itérateur d'entrée. Mais dans tous les autres cas (comme une génération de chaînes compliquée ou certains calculs), je ne me soucierais pas de possibles résultats de performance et de la confiance de la confiance (voir la réponse de Jim) et du compilateur pour l'optimiser comme si cela devrait. Si cela devient un goulot d'étranglement (profil!), Changez-le bien sûr!


1 commentaires

Oui, les itérateurs sont le moyen d'aller habituellement. Sauf si vous utilisez des fonctions virtuelles.



6
votes

Le premier exemple doit être probablement plus comme l'un de ces deux:

void getLines(const std::string &in, std::vector<std::string> &out);
void getLines(const std::string &in, std::vector<std::string> *out);


3 commentaires

Je comprends l'utilité en transmettant l'entrée par référence, qui n'était qu'une surveillance, mais pourquoi une référence de const?


Chaque argument de fonction par référence doit être constitué si son référent n'est pas modifié par la fonction. Cela devrait être une seconde nature. Il aide le compilateur à optimiser et aide le programmateur à comprendre et à utiliser la fonction.


Vous pouvez passer un objet temporaire dans si la fonction accepte une valeur ou une référence de const, mais pas si la fonction accepte une référence non constituée. Ceci est juste l'une des règles de la langue. Donc, le comportement est alors à peu près comme passer de la valeur, en ce que vous pouvez passer un objet temporaire si vous le souhaitez. (Il existe également une certaine protection marginale contre l'obtention de l'objet modifié par la callee - mais pas beaucoup, grâce à mutable et const_cast . Mais des cas où c'est un problème est réellement rare dans entraine toi.)



1
votes

Mon conseil est d'écrire le code afin que l'utilisation du client soit aussi intuitive que possible.

Si - comme c'est habituellement le cas - vous jugez que de retourner par valeur, alors si votre système est critique et que vous trouvez une valeur de retour particulière n'est pas optimisée bien par votre compilateur - même au mieux raisonnable niveau d'optimisation Vous pouvez utiliser et après avoir vérifié les options de ligne de commande pertinentes ou les conseils du compilateur sur la réalisation de la RVO, et envisager des compilateurs alternatifs si pratique - idéalement un compilateur C ++ 11 qui bénéficie de Toujours-efficace Déplacez la sémantique , seulement puis changez l'endroit problématique spécifique pour accepter la valeur de retour par référence.


0 commentaires