401 votes

Est la pratique d’un retour à une variable de référence C++, mal ?

C'est un peu subjectif, je pense; je ne sais pas si de l'avis unanime (j'ai vu beaucoup de fragments de code où les références sont retournés).

Selon un commentaire vers cette question, j'ai simplement demandé, concernant l'initialisation des références, en retournant une référence peut être mal, parce que, [ce que je comprends] il est plus facile de manquer de les supprimer, ce qui peut conduire à des fuites de mémoire.

Ce qui m'inquiète, comme je l'ai suivie des exemples (sauf si je suis en imaginant les choses) et fait cela dans un juste quelques endroits... Ai-je mal compris? Est-il mal? Si oui, comment le mal?

Je sens qu'à cause de mon sac mélangé des pointeurs et références, combiné avec le fait que je suis novice en C++, et la confusion la plus totale sur ce qui à utiliser lors de l', mes applications doit être la mémoire de la fuite de l'enfer...

Aussi, je comprends que l'utilisation de la puce/partagée des pointeurs est généralement admis que la meilleure façon d'éviter les fuites de mémoire, donc merci d'avance pour vos conseils ;)

483voto

GManNickG Points 155079

Voulez-vous dire:

int& getInt(void)
{
    int i;
    return i;
}

C'est toutes sortes de mal. La pile affectés je vais aller loin et que vous ne renvoyant à rien. C'est semi-mal:

int& getInt(void)
{
    int *i = new int;
    return *i;
}

Parce que maintenant, le client dispose de finir par faire de l'étrange:

int& myInt = getInt(); // note the &.
int badInt = getInt(); // the & will be easy to miss (source of problems).
delete &myInt; // must delete.
delete &badInt; // won't work. badInt was a copy of the allocated int, which
                // is now lost forever

Je pense que la meilleure façon de faire quelque chose comme ça, c'est juste:

int *getInt(void)
{
    return new int;
}

Et maintenant, le client stocke un pointeur:

int *myInt = getInt(); // has to be a pointer
int& weirdInt = *getInt(); // but this works too if you really want.
delete myInt; // being a pointer, this is easy to do.
delete &weirdInt; // works.

Maintenant, pour les membres des classes, et est puissant, comme opérateur de chaînage (cout <<), ou de l'opérateur[].

66voto

Charlie Martin Points 62306

N ° Non, non, mille fois non.

Ce qui est mal est une référence à un objet alloué dynamiquement et perdre le pointeur d’origine. Lorsque vous un objet que vous assumez l’obligation d’avoir une garantie .

Mais jetez un oeil sur, par exemple, `` : que doit renvoyer une référence, ou

ne fonctionnera pas.

59voto

David Thornley Points 39051

Vous devez retourner une référence à un objet existant qui ne va pas tout de suite, et où vous n'avez pas l'intention de tout transfert de propriété.

Ne jamais renvoyer une référence à une variable locale ou quelque chose du genre, car il ne sera pas là pour être référencé.

Vous pouvez retourner une référence à quelque chose d'indépendant de la fonction, ce qui vous ne vous attendez pas la fonction d'appel à prendre la responsabilité de la suppression. C'est le cas pour le type operator[] fonction.

Si vous créez quelque chose, vous devez retourner une valeur ou un pointeur (régulier ou smart). Vous pouvez renvoyer une valeur librement, car il va dans une variable ou une expression dans la fonction appelante. Ne jamais renvoyer un pointeur vers une variable locale, car il va disparaître.

16voto

Mehrdad Afshari Points 204872

Il n’est pas mal. Comme beaucoup de choses en C++, il est bon si utilisé correctement, mais il y a beaucoup de pièges que vous devez être conscient de quand vous l’utilisez (comme mais retourne une référence à une variable locale).

Il y a de bonnes choses qui peuvent être obtenus avec elle (comme la carte [nom] = « hello world »)

11voto

John Dibling Points 56814

"de retour d'une référence est mal, parce que, tout simplement [que je comprends] il le fait plus facile à manquer de le supprimer"

Pas vrai. Renvoie une référence n'implique pas la propriété de la sémantique. Qui est, tout simplement parce que vous le faites:

Value& v = thing->getTheValue();

...ne signifie pas que vous possédez maintenant le mémoire visé par v;

Cependant, c'est horrible de code:

int& getTheValue()
{
   return *new int;
}

Si vous faites quelque chose comme cela parce que "vous n'avez pas besoin d'un pointeur sur l'instance" puis: 1) déréférencer le pointeur si vous avez besoin d'une référence, et 2) vous devrez éventuellement le pointeur, parce que vous avez à faire correspondre une nouvelle avec une suppression, et vous avez besoin d'un pointeur à appeler delete.

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