Suis-je l'initialisation de mon C++ référence à des variables correctement?
J'ai essayé de Google cette question, et je ne peux pas trouver quelque chose que je considère comme pertinent. Donc, je dois être à la recherche de quelque chose de mal; néanmoins, j'apprécierais quelques conseils...
Foobar &foobar = *new Foobar(someArg, anotherArg);
Est-ce juste moi ou est-ce que semblent malodorante?
Je comprends que le new
mot-clé est conçu pour une utilisation avec des pointeurs (comme telle):
Foobar *foobar = new Foobar(someArg, anotherArg);
Mais que faire si vous n'avez pas besoin d'un pointeur sur l'instance, et vous souhaitez utiliser une référence à la place? Ou, est-ce le cas que vous n'avez pas besoin d'initialiser explicitement (comme les variables locales); et si c'est le cas, comment faire si je veux initialiser les paramètres?
Le code suivant ne fonctionne pas (sauf si je suis en train de faire quelque chose de mal):
//the last argument is of type: int
Foobar &foobar(someArg, anotherArg);
... donne l'erreur de compilateur:
initialiseur liste des expressions traitées comme expression composée
invalide de l'initialisation de la non-const de référence de type ‘Foobar&"
à partir d'un temporaire de type "int"
Et aussi cela ne semble pas fonctionner:
Foobar &foobar = Foobar(someArg, anotherArg);
... donne l'erreur de compilateur:
erreur: invalid initialisation de la non-const de référence de type
"Foobar&" à partir d'un temporaire de type "Foobar"
Mise à jour 1:
Bare à l'esprit que je suis de retour cette valeur, donc je ne veux pas utiliser une variable locale, je veux utiliser une valeur sur le tas, pas la pile:
Foobar &helloWorld()
{
Foobar &foobar = *new Foobar(someArg, anotherArg);
foobar.HelloWorld();
return foobar;
}
Devrais-je être en utilisant des pointeurs au lieu de cela, ou est-ce tout à fait valide?
Vous êtes mieux de retourner un pointeur. Ou encore mieux, consultez la stl::auto_pointer. De retour de l'un de ceux-ci, et quel que soit le programmeur à l'aide de votre fonction n'est avec le résultat, il sera garanti à supprimer à nouveau sans laisser une fuite.
Correction, je veux dire auto_ptr.
Bon conseil pour les auto_ptr! 🙂 Je vais commencer à l'utiliser qu'au lieu de retourner des références...
) r3n: ce qui est mal. Comment allez-vous jamais savoir quand gratuit Foobar & >:-). Je suis sûr que vous pouvez écrire que si elle ne marche pas, utiliser de nouvelles. Aussi, si vous regardez c++0x, vous trouverez les && de l'opérateur. Dans un an, quand il s'agit de faire Foobar fooVar(someArg, anotherArg); return fooVar; est efficace.
OriginalL'auteur Nick Bolton | 2009-04-15
Vous devez vous connecter pour publier un commentaire.
Pourquoi pensez-vous que vous devez utiliser les nouvelles et les références à tout? Pourquoi pas:
Pour votre retour de fonction d'une valeur:
ou un pointeur:
Si vous le faites, l'appelant est responsable de la suppression de l'allocation d'un objet à un certain point.
Retour d'un non-membre de la fonction est un endroit où les références peuvent généralement pas être utilisées judicieusement, que la chose que vous aimeriez consulter habituellement n'existe plus.
La seconde méthode, je veux dire la méthode: Foobar helloWorld()
La valeur de retour nécessite aworking copie constructeur et le destructeur - si vous avez été l'obtention de la mémoire des erreurs d'accès, l'un de ces (ou les deux) n'est probablement pas mis en œuvre correctement.
+1. L'approche de la valeur de Neil 2e extrait de code est de loin la plus claire et la moins sujette aux erreurs, à condition que Foobar est une valeur de type type et n'est pas trop énorme.
Juste pour clarifier, seul le pointeur de la version des feuilles de l'appelant responsable de la suppression, à droite? Dans la valeur de retour de la version du compilateur va supprimer la valeur copiée à partir de la pile lorsqu'elle est hors de portée de l'appelant.
OriginalL'auteur
Oui, c'est puant!
Si vous "nouveau" quelque chose, l'affecter à un pointeur (ou smart-type de pointeur), il devra être supprimé à nouveau pour éviter une fuite de mémoire. Les références ne sont pas traditionnellement considérés comme étant des choses que vous devez supprimer de nouveau, donc si quelqu'un d'autre voit que le code (l'attribution d'un nouveau ed objet d'une référence), il peut les confondre.
Que vous pouvez faire...
...si vous voulez vraiment une référence. Notez qu'une fois que foobar est hors de portée, l'objet temporaire, il est de référencement va mourir. Mais, il n'y a pas beaucoup de point dans l'écriture que lorsque vous pouvez droit-forwardly écrire:
Vous n'avez probablement pas vraiment besoin d'une référence... ils sont généralement (mais pas exclusivement) utilisés pour les types d'arguments de méthode. Ceci est fait de sorte que vous pouvez passer à quelque chose qui ressemble à un objet, mais seulement la taille d'un pointeur, et dont la méthode peut modifier. La référence a été introduit principalement pour vous permettre d'écrire un constructeur de copie (je ne vais pas expliquer ça ici!).
) r3n c'est correct. const Foobar& foobar serait de travailler. En général, vous ne faites pas de référence pour temp objs, vous passez temp obj dans son ensemble et de les recevoir comme un ensemble (au lieu d'un pointeur/ref)
Scott: Oui, c'est un MSVC bug.
On dirait que vous avez raison informit.com/guides/content.aspx?g=cplusplus&seqNum=199
+1, mais s'il vous plaît mentionner que le temporaire lié à votre const réf dans le 1er extrait sera détruit à la fin de la fonction, ce qui signifie qu'il est inutile de renvoyer une référence à cela, dans le code qui utilise la référence sera susceptible de se bloquer.
OriginalL'auteur Scott Langham
Les références en C++ ne sont vraiment pas aussi fort que les gens s'attendent à être, je pense que la confusion vient de gens qui sont habitués à des langages comme Java et C# qui n'ont pas de pointeurs et des références qui peuvent être réaffectées et utilisé.
Une référence en C++ est généralement utilisé comme un alias pour une variable, de sorte que vous pouvez simplifier les choses, comme la transmission de paramètres et valeurs de retour. Il y a très peu de situations où vous essayez d'acquérir une référence à la façon dont vous êtes en train de faire sur la première ligne. Ainsi, vous n'avez pas besoin de faire ce qu'il semble que vous essayez de le faire 🙂
La deuxième ligne est, bien sûr, correct, et vous pourriez faire quelque chose comme retour *foobar à partir d'une fonction qui retourne une référence.
C'est ok pour revenir références dans des situations où ils sont appropriés, comme les opérateurs, de sorte que vous verrez souvent un retour par référence.
OriginalL'auteur Uri
Votre écriture droite. Mais gardez à l'esprit son bizarre gratuit le ptr en faisant supprimer &refVar; (il peut être confondu avec une variable qui n'a pas été créé par le nouveau).
Vous devriez vérifier GotW pour les bonnes pratiques de passage autour de http://www.gotw.ca/gotw/ je ne me souviens pas qui la leçon qu'il a été (il n'y a plus d'un) mais la lecture par le biais de qui est le plus précieux alors n'importe qui de réaliser (pièges seront moins d'une surprise)
Vous devriez essayer d'écrire du code qui ne JAMAIS utiliser des pointeurs. Je ne mais une fois que suis planté quand j'ai besoin d'un conteneur de BaseObj. Il n'y avait pas de travail autour de cela. Généralement, j'ai utilisé les conteneurs STL et qui ont le plus variable vivant sur la pile { MyClass myVar; ... } ou en tant que membre et de les passer en tant que de besoin.
Son calme, facile à enlever pointeurs une fois que vous commencer à passer de référence au lieu de pointeurs, et l'utilisation des conteneurs stl au lieu de nouveau. Notez que je n'utilise jamais auto_ptr. vecteur, string, deque, la liste et la carte devrait faire la plupart de ce que vous avez besoin. Il y a d'autres conteneurs.
OriginalL'auteur
Non, vous l'avez. Un toto& "points" de l'objet réel, de sorte que si vous voulez vraiment un toto de référence que vous avez à déréférencer les foo pointeur.
@Neil a un point, un point de vue syntaxique, c'est comment vous obtenez ce que vous voulez, mais pourquoi voulez-vous?
OriginalL'auteur Charlie Martin
Je vous recommande d'utiliser un pointeur intelligent. Vous avez besoin pour gérer la propriété, et une référence ne sera pas le faire pour vous. En fait, il va obscur à l'appelant qu'il n'y a aucune question de la propriété. Comme Scott Langham mentionné dans un commentaire, std::auto_ptr serait de travailler. À l'aide de shared_ptr de Boost ou de TR1 pourrait être une meilleure idée.
OriginalL'auteur Fred Larson