Je sais que le titre semble familier car il y a beaucoup de questions similaires, mais je demande un aspect différent du problème (je connais la différence entre avoir des choses sur la pile et les mettre sur le tas).
En Java, je peux toujours renvoyer des références à des objets "locaux".
public Thing calculateThing() {
Thing thing = new Thing();
// do calculations and modify thing
return thing;
}
En C++, pour faire quelque chose de similaire, j'ai 2 possibilités
(1) Je peux utiliser des références chaque fois que j'ai besoin de "retourner" un objet.
void calculateThing(Thing& thing) {
// do calculations and modify thing
}
Ensuite, utilisez-le comme ceci
Thing thing;
calculateThing(thing);
(2) Ou je peux renvoyer un pointeur vers un objet alloué dynamiquement.
Thing* calculateThing() {
Thing* thing(new Thing());
// do calculations and modify thing
return thing;
}
Ensuite, utilisez-le comme ceci
Thing* thing = calculateThing();
delete thing;
En utilisant la première approche, je n'aurai pas à libérer la mémoire manuellement, mais pour moi, cela rend le code difficile à lire. Le problème avec la deuxième approche est que je dois me rappeler de delete thing;
ce qui n'est pas très joli. Je ne veux pas retourner une valeur copiée parce que c'est inefficace (je pense), alors voici les questions que je me pose
- Existe-t-il une troisième solution (qui ne nécessite pas de copier la valeur) ?
- Y a-t-il un problème si je m'en tiens à la première solution ?
- Quand et pourquoi dois-je utiliser la deuxième solution ?
42 votes
+1 pour avoir joliment posé la question.
1 votes
Pour être très pédant, il est un peu imprécis de dire que "les fonctions renvoient quelque chose". Plus correctement, l'évaluation d'un appel de fonction produit une valeur . La valeur est toujours un objet (sauf si c'est une fonction void). La distinction est de savoir si la valeur est une glvalue ou une prvalue -- ce qui est déterminé par le fait que l'on déclare ou non type de retour est une référence ou non.