Sont-ils les mêmes:
int foo(bar* p) {
return p->someInt();
}
et
int foo(bar& r) {
return r.someInt();
}
Ignorez le potentiel de pointeur nul. Ces deux fonctions sont-elles fonctionnellement identiques, peu importe si someInt()
est virtuelle ou si on leur passe un bar
ou une sous-classe de bar
?
Est-ce que cela tranche quelque chose:
bar& ref = *ptr_to_bar;
Les références C++ ne sont pas intentionnellement spécifiées dans la norme à implémenter à l'aide de pointeurs. Une référence ressemble plus à un "synonyme" à une variable qu’à un pointeur. Cette sémantique ouvre certaines optimisations possibles pour le compilateur lorsqu'il est possible de réaliser qu'un pointeur serait une surpuissance dans certaines situations.
Quelques différences supplémentaires:
Ignorant tous les sucres syntaxiques et les possibilités qui peuvent être faites avec l'un et non avec l'autre et la différence entre les pointeurs et les références expliquées dans d'autres réponses (à d'autres questions) ... Oui, ces deux sont fonctionnellement exactement les mêmes! Les deux appellent la fonction et les deux gèrent également les fonctions virtuelles.
Et non, votre ligne ne tranche pas. Il s'agit simplement de lier la référence directement à l'objet pointé par un pointeur.
Quelques questions sur les raisons pour lesquelles vous voudriez utiliser l'une sur l'autre:
Au lieu d'essayer de trouver des différences moi-même, je vous délègue à ceux au cas où vous voudriez savoir.
La référence est un pointeur constant, c'est-à-dire que vous ne pouvez pas modifier la référence pour faire référence à un autre objet. Si vous changez, la valeur de l'objet référent change.
Pour Ex:
int j = 10;
int &i = j;
int l = 20;
i = l; // Now value of j = 20
int *k = &j;
k = &l; // Value of j is still 10
Oui, ils sont fonctionnellement identiques. Étant donné qu'une référence vous obligera à la définir sur un objet avant de l'utiliser, vous n'aurez pas à traiter avec des pointeurs nuls ou des pointeurs vers une mémoire invalide.
Il est également important de voir la différence sémantique:
Je n'ai pas utilisé C++ depuis longtemps, donc je ne vais même pas essayer de vraiment répondre à votre question (désolé); Cependant, Eric Lippert vient de publier un excellent article sur les pointeurs/références que je pensais que je vous indiquerais.
Je ne sais pas si quelqu'un a répondu à votre 2e question cachée en bas sur le tranchage ... non, cela ne causera pas de tranchage.
Le découpage est lorsqu'un objet dérivé est affecté (copié) à un objet de classe de base - la spécialisation de la classe dérivée est "découpée". Notez que j'ai dit que object est copié, nous ne parlons pas de pointeurs copiés/assignés, mais des objets eux-mêmes.
Dans votre exemple, cela ne se produit pas. Vous dé-référencez simplement un pointeur à un objet Bar (résultant ainsi en un objet Bar) utilisé comme valeur r dans une initialisation de référence. Pas sûr d'avoir bien compris ma terminologie ...
Comme tout le monde l'a mentionné, dans la mise en œuvre, les références et les pointeurs sont essentiellement les mêmes. Il y a quelques mises en garde mineures:
Vous ne pouvez pas attribuer NULL à une référence (shoosh l'a mentionné): c'est significatif car il n'y a pas de valeur de référence "non définie" ou "invalide".
Vous pouvez passer une variable temporaire comme référence const , mais ce n'est pas légal de passer un pointeur vers une valeur temporaire.
Par exemple, c'est correct:
class Thingy; // assume a constructor Thingy(int,int)
void foo(const Thingy &a)
{
a.DoSomething();
}
void bar( )
{
foo( Thingy(1,2) );
}
mais la plupart des compilateurs se plaindront
void foo2( Thingy * a);
void bar2()
{
foo( &Thingy(1,2) );
}
void foo()
{
int a = 5;
// this may be slightly more efficient
int &b = a;
printf( "%d", ++b );
// than this
int *c = &a;
printf( "%d", ++(*c) );
}
De même, le mot-clé __ restrict ne peut pas être appliqué aux références, uniquement aux pointeurs.
Vous ne pouvez pas faire d'arithmétique de pointeur avec des références, alors que si vous avez un pointeur dans un tableau, l'élément suivant du tableau peut être obtenu via p + 1, une référence ne pointe que sur une chose dans toute sa vie.
Les fonctions ne sont évidemment pas "les mêmes", mais en ce qui concerne le comportement virtuel, elles se comporteront de manière similaire. En ce qui concerne le découpage, cela ne se produit que lorsque vous traitez des valeurs, pas des références ou des pointeurs.