Retourne la copie de relevé des valeurs
Je me pose des questions sur ce à cause de la question de la portée. Par exemple, considérez le code
typedef struct {
int x1;/*top*/
int x2;/*bottom*/
int id;
} subline_t;
subline_t subline(int x1, int x2, int id) {
subline_t t = { x1, x2, id };
return t;
}
int main(){
subline_t line = subline(0,0,0); //is line garbage or isn't it? the reference
//to subline_t t goes out of scope, so the only way this wouldn't be garbage
//is if return copies
}
Donc ma question est, sera le retour à la déclaration de toujours copier? Dans ce cas, il semble fonctionner, je suis donc amené à croire que le retour ne copie. Si elle ne copie, il copie dans tous les cas?
- Il n'y a pas de références (comme dans
&
- une référence C++) poursubline_t
dans votre code. - Envisagez-vous comme Java/C#, où chaque objet est une référence à quelque chose? Ce n'est pas le cas en C/C++ monde.
- pour vous dire la vérité, j'ai tout simplement ne pas connaître le comportement de C/C++ lors du retour d'une variable dans la portée locale. Eh bien, je savais que ses beaux-faire avec des entiers par exemple, mais je savais aussi qu'il fallait être prudent dans certains cas (comme retournant un pointeur vers un objet instancié sur place.) Je ne connaissais pas le comportement que le C/C++ adopte pour la des structures.
- prochaine fois que vous modifiez quelqu'code assurez-vous qu'il atleast compile .....
Vous devez vous connecter pour publier un commentaire.
Oui, dans ce cas, il y aura une copie. Si vous modifiez la déclaration de la fonction comme ceci:
alors aucune photocopie ne sera faite. Cependant, dans votre cas particulier, il ne serait pas valide pour renvoyer une référence à un objet alloué sur la pile. Le problème est que l'objet serait détruite, et invalidé avant que l'appelant avait une chance de l'utiliser.
Ceci est lié à la commune Valeur De Retour D'Optimisation pour le C++ qui peuvent éviter de faire une opération de copie réelle dans le cas que vous avez décrit. Le résultat final est (ou devrait être) le même que si une copie a été effectuée, mais vous devez être conscient de l'optimisation. La présence de cette optimisation peut, dans certains cas, modifier le comportement observable du programme.
&
, aucune photocopie ne sera faite dans le cas décrit dans la question, mais le résultat de l'opération de programme serait défini. Cependant, il serait tout à fait légal si l'objet retourné n'étaient pas localement d'étendue variable.Dans votre cas , il sera de retour une copie
Si votre code a été
alors il serait de retour d'une référence, ce qui donnerait dans un comportement indéterminé.
this
, ou allouées sur la pile d'objet est parfaitement bien.Oui, pour une fonction déclarée pour retourner un
struct
,return
d'une telle structure de la copie (même si le compilateur est habilité à optimiser la copie à l'écart, essentiellement dans les cas où il peut prouver l'optimisation est sémantiquement inoffensif, vous pouvez raisonner "comme si" la copie a été garanti).Cependant, puisque vous ne tag ce que C++, pas du C, pourquoi ne pas fournir votre
struct
avec un constructeur, au lieu...? Semble plus clair et plus direct...!-)struct
avec un constructeur de copie quand il ne veut pas faire quelque chose de différent de ce qu'un défaut constructeur de copie n'? En outre, cela permettrait de rendre non-POD, ce qui peut être important d'ailleurs.class
etstruct
est queclass
membres et les classes de base sontprivate
par défaut, alors questruct
membres et les classes de base sontpublic
par défaut. Sinon, ils fonctionnent exactement de la même.subline
fonction doit juste se transformer en unsubline_t
ctor, c'est juste de plus!typedef struct
, mais oui, l'original est dans cet étrange langage C/C++.Il retournera toujours une copie.
Si vous voulez éviter l'impact sur les performances de la copie de l'objet sur le retour, vous pouvez déclarer un pointeur, créer une instance de l'objet à l'aide de nouvelles, et de renvoyer le pointeur. Dans ce cas, le pointeur va être copiée, mais l'objet ne sera pas.
oui , le retour est une copie
Si vous mettez un referencer, alors ce n'est pas une copie
Returing objets en C++ fait par valeur et non par référence.
Non, l'objet est copyed.
Oui et non... du point de vue Sémantique, il se comporte comme copier, mais il y a quelque chose qui est appelé valeur de retour d'optimisation qui permet d'économiser constructeur de copie.
Retourne une copie, qui est ce que vous voulez qu'il fasse. Changement pour retourner une référence entraînera un comportement indéterminé dans l'attribution de la ligne.
Cependant, la idiomatiques façon de le faire en C++ est avec des constructeurs et de l'affectation des listes. Cette encapsule le code et les données des structures plus, et vous permet d'éviter la pléthore d'objets intermédiaires que les compilateurs sont libres de construire/détruire/copier.
Pour la structure
subline_t
vous avez définie, oui, il retournera toujours une copie.Le retour de classe ou structure peut ou ne peut pas être copié, selon si le compilateur utilise une copie élision. Voir les réponses à Ce sont des copier élision et la valeur de retour d'optimisation?
En bref, s'il est copié ou non dépend d'un certain nombre de choses.
Bien sûr, vous pouvez éviter une copie en retournant une référence. Dans le cas de votre exemple, en retournant une référence n'est pas valide (bien que le compilateur le permettra) parce que le local struct est alloué sur la pile, et à cet effet, le retour de la référence est une désallocation de l'objet. Toutefois, si l'objet a été transmise à votre fonction (directement ou en tant que membre d'un objet), vous pouvez revenir en toute sécurité une référence et éviter le copier-sur-retour.
Enfin, si vous ne pouvez faire confiance à copier élision et vous voulez éviter les copies, vous pouvez l'utiliser et le retour d'un
unique_ptr
au lieu d'une référence. L'objet lui-même ne sera pas copié, bien que launique_ptr
lui-même peut ou peut ne pas être (encore une fois, en fonction de copie élision!). Copier/déplacer uneunique_ptr
est cependant très bon marché si la copie élision de launique_ptr
ne se fait pas pour une raison quelconque.Voici un exemple d'utilisation de
unique_ptr
:Notez que vous devez (malheureusement) déclarer un constructeur pour votre structure, ou d'autre
make_unique
ne compilera pas à cause des lacunes de C++.Juste pour info, car dans ce cas, vous utilisez uniquement un struct(ure), c'est le même comportement que dans le langage C.
Si c'est une fonctionnalité du langage, il est recommandé qu'il ne doit pas être utilisé
Je ne suis pas d'accord et vous RECOMMANDONS PAS de retour vecteur pour modifier les valeurs:
Est beaucoup plus rapide passe comme référence:
J'ai testé sur VS2015 avec les résultats suivants en mode release:
Par la référence:8.01 MOPs et le retour de vecteur: 5.09 MOPs 60% pour le pire!
En mode debug, les choses sont bien pires:
Par la référence:0.053 MOPS et retour vecteur: 0.034 MOPs
return std::move(c)
, et vous acceptez de vecteurs en valeur lorsque vous n'en avez pas besoin.std::move
peut-être pas nécessaire mais le fait demeure que vous êtes la copie des tas de choses que vous n'avez pas à et de il est de ruiner la validité de votre référencestd::move
(ce qui est redondant au moment de la compilation) à faire la moitié aussi vite, et certainement pas pour faire de votre sans rapport avec la mise en œuvre plus rapide. Vous devez revoir votre technique d'évaluation des performances. Les conseils donnés dans cette page par des experts.