Différence entre les arguments de la fonction déclarée avec & et * en C++
J'ai tapé l'exemple suivant:
#include <iostream>
double f(double* x, double* y)
{
std::cout << "val x: " << *x << "\n";
std::cout << "val y: " << *y << "\n";
return *x * *y;
}
double f2(double &x, double &y)
{
std::cout << "val x: " << x << "\n";
std::cout << "val y: " << y << "\n";
return x * y;
}
int main()
{
double a, b;
a = 2;
b = 3;
std::cout << f(&a, &b) << "\n";
std::cout << f2(a, b) << "\n";
return 0;
}
Dans la fonction f
je déclare x et y comme des pointeurs de qui je peux obtenir la valeur en utilisant *x
. Lors de l'appel de f
j'ai besoin de passer l'adresse de mon passé arguments, c'est pourquoi je passe &a, &b
. f2
est le même à l'exception de la définition est différente.
Maintenant, ma question est: Sont-ils vraiment la même chose concernant la gestion de la mémoire? Les deux ne font aucune copie de la valeur passée mais au lieu de passer une référence?
Je me demande sur f2
parce que je ne pouvais pas lire l'adresse de x
dans f2
donc je savoir plus à propos de x et y dans f
(là, je sais, adresse ET valeur).
Merci d'avance!
Modifier: Ok merci, après avoir fait un peu plus de recherche, j'ai trouvé un très utile sujet:
Pointeur vs Référence
Il y a également un lien vers google directives de codage http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Reference_Arguments qui est tout à fait useful
je me sens (ce que j'ai compris maintenant, c'est une forme de l'objet goût) pour faire plus de clair
- Ce n'est pas C, c'est le C++.
- Ah je vois, donc en C, j'ai toujours utiliser des pointeurs, ok merci! Ne le savais pas jusqu'à présent!
- >Google guide de style - l'éviter. Il était dépassé en 2008 (date de aswer), et c'est encore pire aujourd'hui.
- Ok merci pour les informer!
- éviter laquelle? le " f " du style ou de la 'f2' style?
- Éviter les Google Guide de Style. Il est tout à fait obsolète.
Vous devez vous connecter pour publier un commentaire.
f2
est de prendre c'est des arguments par référence, qui est essentiellement un alias pour les arguments que vous avez pass. La différence entre pointeur et référence est une référence ne peut pas être NULL. Avec lef
vous avez besoin pour passer le adresse (à l'aide de & operator) des paramètres que vous passez le pointeur, où, quand vous passez par référence vous venez de passer les paramètres et l'alias est créé.Passage par référence const (
const double& ref
) est préféré lorsque vous n'allez pas changer les arguments à l'intérieur de la fonction, et lorsque vous vous apprêtez à changer, l'utilisation non-const de référence.Pointeurs sont principalement utilisés lorsque vous en avez besoin pour être en mesure de passer
NULL
à vos paramètres, évidemment, vous aurez besoin de vérifier à l'intérieur de votre fonction si le pointeur n'a pas étéNULL
avant de l'utiliser.C'est juste sucre syntaxique pour éviter d'avoir à utiliser
*
chaque fois que vous faites référence à l'argument. Vous pouvez toujours utiliser&
d'avoir l'adresse dex
dansf2
.Une autre différence qui n'a pas été mentionné, c'est que vous ne pouvez pas changer ce qu'un renvoi fait référence. Cela ne fait pas beaucoup de différence dans l'appel de fonction exemple montré dans la question d'origine.
rY
toujours des points àY
et ne peut pas être déplacé.Références ne peut pas être utilisé pour indexer dans des tableaux simples comme des pointeurs.
Dans ma tête, les paramètres des fonctions sont toujours passé par valeur. Passage d'un
int
est facile d'imaginer, en passant undouble
est juste plus grand et le passage d'unstruct
ouclass
pourrait être très grande en effet.Mais en passant un pointeur vers quelque chose, eh bien, vous êtes juste de passage d'une adresse en valeur. (Un pointeur est souvent une taille appropriée pour le CPU comme un
int
.)Une référence est très similaire, et certainement, je pense à une référence comme un pointeur, mais avec du sucre syntaxique pour la faire ressembler à l'objet de son renvoi a été transmis par valeur.
Vous pouvez aussi penser à une référence en tant que
const
pointeur, c'est à dire:Donc, un pointeur ne le double de temps: C'est une valeur sur dans son propre droit, mais il peut également point à un autre de valeur lorsque vous déréférencement d'elle, par exemple:
*p
.Aussi, pour avoir des paramètres de référence signifie que vous ne pouvez pas faire référence à quelque chose d'autre pendant la durée de vie de la fonction, car il n'y a aucun moyen d'exprimer cela.
Une référence est supposée ne pas être en mesure d'être initialisé avec des
null
, mais pensez à ceci:Cela signifie que les pointeurs doit être vérifié avant de vous les utilisez, mais les références ne peuvent pas être vérifiés. La mise en œuvre de
foo()
pourrait essayer de lire ou d'écrire dansi
qui va provoquer une violation d'accès.Dans l'exemple ci-dessus le pointeur de la
p
devrait ont été vérifiées avant d'être utilisées dans l'appel àfoo
:void foo(int& i);
exemple-à-dire quel est exactement le problème avec l'appeler avec unNULL
pointeur.Vous auriez été en mesure de lire
x
adresse dans les deux fonctions.De le faire dans
f2
, vous devez bien sûr préfixex
par un&
depuis,x
est un référence à un double, et que vous voulez un adresse.Un bon de remarquer la différence entre les références et les pointeurs, c'est que l'ancien ne peut pas être NULL. Vous doit passer quelque chose (valide), tandis que lors de la fourniture d'un pointeur, vous devez indiquer dans la documentation si le passage de la valeur NULL est autorisé/bien définis.
Une autre différence est une question de lisibilité: à l'aide des références à la place des pointeurs (si possible) rend le code moins encombré avec
*
et->
.