Le retour de l'objet à partir de la fonction

Je suis vraiment confus maintenant sur la manière et la méthode à utiliser pour objet de retour d'une fonction. Je veux des commentaires sur les solutions pour les exigences.

Scénario A:
L'objet retourné doit être stocké dans une variable qui n'a pas besoin d'être modifiée au cours de sa durée de vie. Ainsi,

const Foo SomeClass::GetFoo() {
 return Foo(); 
}

invoquée comme:

someMethod() {
 const Foo& l_Foo = someClassPInstance->GetFoo();
//...
}

Scneraio B:
L'objet retourné doit être stocké dans une variable qui sera modifiée au cours de sa durée de vie. Ainsi,

void SomeClass::GetFoo(Foo& a_Foo_ref) {
     a_Foo_ref = Foo(); 
    }

invoquée comme:

someMethod() {
 Foo l_Foo;
 someClassPInstance->GetFoo(l_Foo);
//...
}

J'ai une question ici: Permet de dire que Toto ne peut pas avoir un constructeur par défaut. Puis comment voulez-vous que dans cette situation, puisque l'on ne peux pas écrire ça:

Foo l_Foo

Scénario C:

Foo SomeClass::GetFoo() {
 return Foo(); 
}

invoquée comme:

someMethod() {
 Foo l_Foo = someClassPInstance->GetFoo();
//...
}

Je pense que ce n'est pas l'approche recommandée car elle entraînerait la construction supplémentaires temporaires.

Qu'en pensez-vous ? Aussi, ne vous recommander une meilleure façon de gérer cela à la place ?

  • en.wikipedia.org/wiki/Return_value_optimization
  • le scénario est bien, mais vraiment aucune amélioration par rapport à C. j'utilise C, à moins que Foo est le constructeur par défaut est "rapide", Foo copie ctor est "lent" et vous ne voulez pas compter sur le compilateur assez intelligent pour éluder les recopies inutiles auquel cas B est également acceptable.
  • notez que a_Foo_ref = Foo(); crée l'objet et réalise la copie. Il est à peu près équivalente pour le dernier scénario
  • Non, il n'est pas. Cette déclaration est autorisé à construire un seul objet.
  • Je l'ai fait lire à ce sujet dans Plus Effective C++(page 104). Le scénario C est également recommandé de là. Il est suggéré que le compilateur d'optimiser le scénario C et de la "construction de l'objet défini par le retour de l'expression à l'intérieur de la mémoire allouée pour l_Foo", réduisant ainsi le coût total de temporaires à 0. Je ne sais pas comment le compilateur pourrait le faire, mais je prends de l'auteur de la parole pour l'instant. Ma question est alors, quand nous avons de grands objets, pourquoi est-Scénario C puis pas recommandé ? On m'a toujours dit qu'il implique la création/suppression d'temporaires et donc recommandé d'utiliser B.
  • Toutes les recommandations pour l'utilisation de B sont probablement des gens qui ont été en utilisant les compilateurs sans RVO/NRVO. Il fut un temps où ce n'était pas une commune de l'optimisation. Cependant, presque à chaque compilateur fait dans la dernière décennie met en œuvre RVO/NRVO, de sorte que vous devriez être bien.
  • Oui, il continue de s'appliquer dans ce cas. La façon dont RVO fonctionne, c'est que le code d'appel qui alloue de la mémoire pour l'objet, puis passe l'adresse de la mémoire à la fonction, qui construit alors l'objet retourné dans cette mémoire. L'appel de la add() fonction dans votre exemple ne serait pas interférer avec qui. Une chose qui peut causer la RVO à ne pas fonctionner, cependant, c'est lorsque la fonction crée plusieurs objets et peut renvoyer l'un d'entre eux, comme illustré ici: en.wikipedia.org/wiki/...

InformationsquelleAutor brainydexter | 2010-04-11