9
votes

Retour des pointeurs ou des références des fonctions C ++

Lorsque vous souhaitez renvoyer une instance d'une méthode, créez-vous l'objet et envoyez-vous un pointeur arrière, ou une référence en arrière? Quelle est la méthode correcte et la signature de méthode pour cela?


8 commentaires

Méthode ou fonction. Les deux sont distincts et la réponse peut être différente.


@Martin - comment ça va? Vous parlez-vous aux fonctions membres comme méthodes et fonctions non membres en tant que fonction?


@naivnomore: Oui (c'est la définition standard dans OO).


Il n'y a pas de choses comme des fonctions non membres dans OO. Vous ne pouvez pas appliquer le terme "méthode" si arbitrairement. Qu'en est-il == ou tout autre morceau de l'interface qui pourrait être / ou?


@Martin: IIRTIC, à Pascal une "méthode" était ce qu'est un Void La fonction est en C. une "fonction" est ce que toute autre fonction est en C. et je suppose @noah a un très valide point. Je suppose donc qu'il n'y a pas de définition standard de "méthode" vs "fonction".


@SBI: à Pascal: fonctions qui n'ont rien retourné sont appelées "procédures". Et je ne vois pas Noah faire de point comme je trouve son commentaire illisible. Mais je suis d'accord, il n'y a pas de définition standard, mais il y a une pertinence (vous devez simplement utiliser le contexte et le bon sens).


@Martin: ah, oui, "procédure", c'était c'était. Il y a très longtemps que j'ai fait Pascal. :) Le point de Noé que je faisais appelé était que, dans Pure OO, il n'y a pas de fonctions non membres. Il semble donc une affirmation douteuse que OO appelle les non-membres tout. Dans certaines langues de OO (comme Java), j'entends beaucoup le terme méthode (bien sûr appliquée aux fonctions des membres, car il n'y en a pas d'autre dans ces langues), mais en C ++, j'entends habituellement la fonction membre vs non membre (ou Fonction libre).


Laissez-moi reformuler (pour ceux qui ont des problèmes avec contexte), alors: @naivnomore: Oui (c'est la définition relativement standard dans les livres C ++ lors de la référence à OO).


6 Réponses :


8
votes

Il y a beaucoup de façons de le faire en C ++. Malheureusement, la plupart d'entre eux entraînent la confusion sur qui est responsable de l'attribution et de la réception de l'objet. Il y a deux méthodes que je recommande: xxx


7 commentaires

Je suis d'accord avec ce commentaire. Il convient de noter que Shared_PTR le faisait en TR1 et est implémenté dans la GCC et Visual Studio comme STD :: TR1 :: Shared_PTR. Unique_ptr doit être noté si vous avez défini des "éviers" et "sources" bien définis ... mais c'est techniquement c ++ 0x. Si vous utilisez uniquement C ++ 98 ... Vous pouvez utiliser Auto_PTR pour cela. Mais unique_ptr est supérieur à tous égards.


Qu'en est-il d'une référence à un membre (rappelez-vous que le message original était d'une méthode non une fonction).


Je ne crois pas que vous puissiez renvoyer une référence à un objet local alloué sur la pile. F va sortir de la portée quand vous revenez de getfoo1


Il revient par valeur pour obtenir Foxo1 et non par référence.


Ne retournez pas un Shared_PTR sauf si vous essayez d'appliquer une utilisation permanente de Shared_PTR. Vous ne pouvez pas obtenir le pointeur une fois que c'est dans l'une d'entre elles. Ainsi, vous ne pouvez pas vous assigner à un pointeur unique, pointeur unique, ou quoi que ce soit d'autre pour mieux servir les besoins du client requérant.


@navinomore faux. J'ai compilé le code comme celui-là juste pour m'assurer que cela s'est écrasé lorsque j'ai essayé de fonctionner sur la valeur de retour. Il est hors de portée et est supprimé dès que vous quittez GetFoo1.


@CrazyX: Si Naivnomor est correct. La valeur est renvoyée par la valeur. Cela signifie qu'il sera copié hors de la fonction à l'aide du constructeur de copie (à moins que la RVO n'est appliquée par le compilateur), mais une fois la fonction renvoyée, les valeurs ont déjà été déplacées (en vigueur) déjà déplacées de la fonction de la fonction.



4
votes

Si je crée une instance purement de retour, je reviendrai par la valeur comme première préférence.

Seulement si le type d'objet n'était pas pratiquement copieux, je envisagerais de revenir via un pointeur intelligent encapsulant le transfert de propriété.

Renvoyer une référence I Réservez pour renvoyer une référence à un objet dont la propriété n'est pas transférée hors de la fonction, elle est déjà la propriété de quelque chose d'autre et que l'existence est garantie jusqu'à la date définie après le retour de la fonction.


0 commentaires

2
votes

Si vous faites référence à quelque chose comme un Méthode d'usine , généralement, vous retournez un pointeur . Mieux encore, renvoyez un pointeur intelligent et vous ne créez pas plus de fuites en utilisant un pointeur brut.

Exemple: P>

std::auto_ptr<Gizmo>  MyFactory::CreateGizmo()
{
  return new Gizmo;
}


0 commentaires

6
votes

soit retour par valeur (les personnes supposent de manière incorrecte que cela est lent) ou, si vous retournez une substitution d'un type polymorphe, renvoyez un auto_ptr (ou mieux un article_ptr en C ++ 0x).

La raison pour laquelle vous n'utilisez pas un Shared_PTR est que vous ne pouvez jamais obtenir votre pointeur hors de celui-ci et utiliser une autre propriété sémantique.

Ne retournez jamais une référence à une instance locale.


1 commentaires

Bien qu'un peu obsolète, il y a un bon article de Scott Meyers le long de ces mêmes lignes que cette réponse ici: aristeia.com/papers/resourcerturnProblem.txt



0
votes

Cela dépend vraiment de la portée de votre instance qui contrôle la durée de vie de l'instance. S'il s'agit d'une instance locale, vous pouvez revenir en valeur mais entraînera le coût de la construction et de la destruction de l'objet deux fois (sauf si vous n'utilisez RVO ). L'autre option consiste à renvoyer un pointeur en construisant l'objet dans le tas dans votre fonction. Toutefois, avec cette approche, le client sera responsable de la suppression de la mémoire allouée et est toujours sujette aux fuites de mémoire. C'est pourquoi vous devrez utiliser une sorte de pointeur intelligent. Le code ABEL Anders illustre clairement les deux approches ci-dessus avec des exemples de code. BTW, vous ne pouvez pas renvoyer une référence à une instance locale depuis que l'instance s'éteindra une fois que la fonction se termine.


0 commentaires

8
votes

La réponse dépend de ce que vous faites exactement et qui est responsable de la localisation.

première méthode: allouer sur le tas et le retour. Qui a été appelé la fonction sera responsable de la suppression du pointeur retourné. xxx

puis dans une autre fonction xxx p> secondaire Méthode: renvoyer une référence. Vous devez faire attention à ne pas sortir de la portée en retournant des variables locales ou temporaires.

ne faites pas cela: xxx

Vous pouvez renvoyer des références aux variables de membre ou des variables passaient comme des arguments sur la fonction. xxx


0 commentaires