[C++] Une référence ou un pointeur?

Une référence ou un pointeur? [C++] - C++ - Programmation

Marsh Posté le 30-05-2002 à 14:45:30    

Voilà une petite question sur les références et les pointeurs: je ne vois pas la différence entre les deux à part leurs façons d'être utiliser (par exemple pour une class: -> avec les pointeurs, normalement avec les références).

Reply

Marsh Posté le 30-05-2002 à 14:45:30   

Reply

Marsh Posté le 30-05-2002 à 14:51:01    

un pointeur est une variable, une référence est l'adresse d'une variable
 
ex :
 
int *a;
int b;
 
a est un pointeur, ie une variable contenant une adresse mémoire
b est une variable normale
&b est une référence à cette variable


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 30-05-2002 à 15:19:14    

Une référence ne peut pas rien référencer, contrairement à un pointeur qui peut être NULL;
De plus, une référence ne peut pas changer d'objet référencé. Elle désigne toujours le même objet, on peut pas changer.
Avec une référence, tout se passe comme si tu manipulais directement l'objet. T'as même pas à te soucier de savoir si c'est une référence ou pas ta variable. Pour écrire ton code ça change rien.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 30-05-2002 à 16:10:47    

HelloWorld a écrit a écrit :

Une référence ne peut pas rien référencer, contrairement à un pointeur qui peut être NULL;
De plus, une référence ne peut pas changer d'objet référencé. Elle désigne toujours le même objet, on peut pas changer.
Avec une référence, tout se passe comme si tu manipulais directement l'objet. T'as même pas à te soucier de savoir si c'est une référence ou pas ta variable. Pour écrire ton code ça change rien.



 
Euh... si quand même : avec les références, il faut créer un "objet vide" pour remplacer le pointeur NULL.

Reply

Marsh Posté le 30-05-2002 à 18:56:09    

je fais du copier coller d'un autre post  
 
http://forum.hardware.fr/forum2.ph [...] h=&subcat=
 
-----------------------------
 
en fait le truc tout con a se dire pour comprendre
c'est que la reference n'est pas un pointeur
"c'est l'objet lui-meme".
 
Ainsi  
 
int toto = 3;
int &reftoto = toto;
 
Toute modif de reftoto va se repercuter sur toto tout simplement parce que reftoto EST toto et vice et versa, ce n'est pas un pointeur ou je ne sais quoi d'autre c'est un simple renommage (un synonyme ou un alias).
 
Quel est l'utilité ici? Dans l'exemple ci-dessus a pas grand chose mais en fait vous pouvez vous dire que ca sert a etendre le scope (la portée) d'une déclaration.  
 
Je vais tenter d'expliquer par un exemple : en C/C++, tu as deux portées la portée d'allocation et la portée de déclaration, exemple une variable membre d'une classe a la durée de vie d'une instance de cette classe mais s'il est privé, seule une methode de la classe peut l'adresser par son nom. Pour y accéder, il faut un accesseur qui renverra soit un pointeur soit une reference vers cet objet. L'utilisation d'un pointeur ne se justifie pas si la variable membre n'est pas un pointeur lui-meme et de toute facon il sera suivi d'un deferencement (par *) inutile. Ce qu'on fait c'est qu'on déclare localement la ou l'on veut utiliser et modifier la variable originale une reference, un alias, qui désignera simplement la variable d'origine.
 
Exemple:
 
class foo{
private:
 int m_toto1;
 int m_toto2;
public:
 int & getToto(bool _boolIndex) {  
   if (_boolIndex)  
     return m_toto1;
   else
     return m_toto2;
 }
}
 
//quelques lignes plus loin
int & aliastoto = fooInstance->getToto(true);
// Ici on peut utiliser et modifier fooInstance.m_toto1  
 
C'est du bon sens mais une reference ne peut designer un objet qui n'est plus valide (s'il a ete desalloué).
Erreur classique: on renvoie une reference d'un objet alloué sur la pile. Ou dans l'exemple ci dessus, si on fait un delete fooInstance; aliastoto devient invalide.
 
Effectivement tout peut se faire avec des pointeurs
SAUF que tu n'es pas garanti que le pointerToValue
est un pointeur valide!
Et tu es obligé de faire une operation de deferencement:
(*pointerToValue) pour manipuler ton entier.
 
En fait le pointeur est une maniere "detournée" de manipuler des alias et des references! (comme au final tout va se retrouver en assembleur qui ne connait que les pointeurs, les jump..)  
 
J'espere que ca aura un peu eclairé le monde sur ce qu'est une reference.
 
LEGREG

Reply

Marsh Posté le 30-05-2002 à 18:58:57    

Smaragdus a écrit a écrit :

 
 
Euh... si quand même : avec les références, il faut créer un "objet vide" pour remplacer le pointeur NULL.  




 
Ben justement si tu fais ça c que t'as rien compris aux références. En effet c'est la raison d'exister des références: supprimer le pointeur NULL.


---------------
Le Tyran
Reply

Marsh Posté le 31-05-2002 à 15:49:31    

LetoII a écrit a écrit :

 
 
Ben justement si tu fais ça c que t'as rien compris aux références. En effet c'est la raison d'exister des références: supprimer le pointeur NULL.  




 
Et comment tu fais si un méthode peut recevoir un objet NULL (c'est à dire pas d'objet) ? Ben justement tu utilises un objet vide ou neutre.

Reply

Marsh Posté le 31-05-2002 à 15:52:58    

Smaragdus a écrit a écrit :

 
Et comment tu fais si un méthode peut recevoir un objet NULL (c'est à dire pas d'objet) ? Ben justement tu utilises un objet vide ou neutre.  




 
cela n'a rien a voir avec les references et les pointeurs
ce sont juste des conventions de programmation..
(exemple: on considere que le pointeur NULL est un cas d'erreur, ou alors qu'une entree optionnelle accepte une chaine vide..)
 
LeGreg

Reply

Marsh Posté le 31-05-2002 à 15:56:28    

legreg a écrit a écrit :

 
 
cela n'a rien a voir avec les references et les pointeurs
ce sont juste des conventions de programmation..
(exemple: on considere que le pointeur NULL est un cas d'erreur, ou alors qu'une entree optionnelle accepte une chaine vide..)
 
LeGreg  




 
tout à fait, j'ai pas dit le contraire mais force est de constater qu'utiliser systématiquement des références entraine certaines conséquences dont il faut tenir compte.

Reply

Marsh Posté le 31-05-2002 à 16:52:35    

Smaragdus a écrit a écrit :

 
 
Et comment tu fais si un méthode peut recevoir un objet NULL (c'est à dire pas d'objet) ? Ben justement tu utilises un objet vide ou neutre.  




 
je vois pas trop où tu veux en venir avec ton objet NULL.


---------------
Le Tyran
Reply

Marsh Posté le 31-05-2002 à 16:52:35   

Reply

Marsh Posté le 31-05-2002 à 16:53:39    

letoII a écrit a écrit :

 
 
je vois pas trop où tu veux en venir avec ton objet NULL.  




 
On s'est tous les 2 pas compris, c'est pas grave...

Reply

Marsh Posté le 31-05-2002 à 16:55:49    

Smaragdus a écrit a écrit :

 
 
On s'est tous les 2 pas compris, c'est pas grave...  




 
 :lol:  
HA si le langage parlé été aussi simple qu'un langage de programmation


---------------
Le Tyran
Reply

Marsh Posté le 31-05-2002 à 22:06:03    

la logique du langage parler est la meme :D demande a monsiieur Bool  
 :sarcastic:  :pt1cable:

Reply

Marsh Posté le 01-06-2002 à 11:39:10    

letoII a écrit a écrit :

 
 
je vois pas trop où tu veux en venir avec ton objet NULL.  




 
Ben par exemple quand t'as une fonction qui renvoie plusieurs  valeurs :
 
GetDimensions(int& x, int& y);
 
Si tu ne veux que la dimension en x tu ne peux pas faire :
 
int dimx;
GetDimensions(dimx, 0);
 
Alors qu'avec les pointeurs c'était possible

Reply

Marsh Posté le 01-06-2002 à 11:53:42    

j'ai l'impression que les gens n'ont pas bien compris
que references != pointeurs...
 
Donc je repete: une reference ce n'est pas un pointeur en C++
et un pointeur n'est pas une reference.
 
Aux dernieres nouvelles dans un programme en C++, il est tout a fait valide d'utiliser les references ET les pointeurs.

Reply

Marsh Posté le 01-06-2002 à 12:35:06    

Ace17 a écrit a écrit :

 
 
Ben par exemple quand t'as une fonction qui renvoie plusieurs  valeurs :
 
GetDimensions(int& x, int& y);
 
Si tu ne veux que la dimension en x tu ne peux pas faire :
 
int dimx;
GetDimensions(dimx, 0);
 
Alors qu'avec les pointeurs c'était possible  




GetDimensions(dimx, 0); Avec des pointeurs est la meilleur façon d'avoir une conneire à l'éxécution (t'as qu'a essayer strlen(0) pour t'en persuader)
 
Si t'as fonction renvoie deux coordonée c qu'il y a une raison di tuveux autoriser un utilisateur à ne récupérer que x tu surcharge ta fonction.


---------------
Le Tyran
Reply

Marsh Posté le 01-06-2002 à 14:17:40    

LetoII a écrit a écrit :

 
Si t'as fonction renvoie deux coordonée c qu'il y a une raison di tuveux autoriser un utilisateur à ne récupérer que x tu surcharge ta fonction.  




 
Pas forcément, il suffirait que GetDimensions vérifie les parametres pour savoir quelles dimensions elle doit renvoyer

Reply

Marsh Posté le 03-06-2002 à 11:31:44    

Références et pointeurs utilisent un même principe:
Manipuler des objets indirectement. A distance, en quelque sorte.
 
 
Un pointeur est un mécanisme "bas niveau".
Ils peut prendre une valeur spéciale, NULL, indiquant qu'ils ne désigne rien de valide.
On peut manipuler soit le pointeur lui-même, soit ce qu'il désigne (par une indirection explicite).
 
Le code est plus explicite, mais plus chargé, plus complexe, et une erreur est très vite arrivée.
Donc plus de possibilités, mais plus délicat à manier.
 
 
Une référence est plutôt "haut niveau".
Elle est constante et ne doit pas être invalide.
Elle est transparente: là où une référence est attendue, on mentionne un objet, et elle devient synonyme de cet objet.
Les références sont très probablement implémentées par des pointeurs, mais on ne doit pas tenir compte ! En effet, c'est au compilateur de savoir comment les gérer, pas à l'utilisateur.
 
Le code est plus clair et sûr (le compilateur peut faire des vérifications de type), mais on voit moins bien se qui se passe.
Donc moins de possibilités, mais plus facile à manier.
 
 
Au passage, une référence Java est un mélange des deux:
-Comme une référence C++: Synonyme de l'objet qu'elle désigne.
-Comme un pointeur C: Peut être null, est variable.


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 03-06-2002 à 12:01:07    

legreg a écrit a écrit :

j'ai l'impression que les gens n'ont pas bien compris
que references != pointeurs...
 
Donc je repete: une reference ce n'est pas un pointeur en C++
et un pointeur n'est pas une reference.
 
Aux dernieres nouvelles dans un programme en C++, il est tout a fait valide d'utiliser les references ET les pointeurs.  




Le probleme viens de non-existance des references en C, et donc de l'utilisation de pointeurs en lieu et places de references...
 
oui une reférence peut etre remplacée par un pointeur.
en fait elle peut etre implementée par un pointeur, mais ce n'est pas la meme semantique...

Reply

Marsh Posté le 03-06-2002 à 12:03:40    

LetoII a écrit a écrit :

 
GetDimensions(dimx, 0); Avec des pointeurs est la meilleur façon d'avoir une conneire à l'éxécution (t'as qu'a essayer strlen(0) pour t'en persuader)
 
Si t'as fonction renvoie deux coordonée c qu'il y a une raison di tuveux autoriser un utilisateur à ne récupérer que x tu surcharge ta fonction.  




cela fait partie de la convention d'utilisation de la fonction !

Reply

Marsh Posté le 04-06-2002 à 11:33:36    

une petite parabole pour faire la distinction entre pointeur, reference et valeur.
 
Imaginez une compagnie qui a des contrats (objets).
Quand un contrat est créé (construit) il est rangé dans un tiroir (case mémoire).
 
Premiere situation, passage par valeur:
l'employé A a besoin du contrat comme document de travail, il demande a l'employé B de lui envoyer le contrat. Comme l'employé B sait que le contrat est unique et precieux et qu'en plus l'employé A est assez peu soigneux et qu'il risque de le déchirer, de faire des ratures, des surlignements ou des ajouts dans la marge, plutot que de lui passer le vrai contrat, il va lui envoyer une copie ce qui l'oblige a passer par la photocopieuse au préalable (constructeur par copie). Quand l'employé A a fini son travail, la copie est détruite ou il peut en faire une copie propre qui servira de base a un nouveau contrat.
 
Deuxieme situation, passage par reference:
le commercial A doit faire signer le contrat par le client, et demande a l'employé B de lui envoyer le contrat. Pas possible pour l'employé B de lui envoyer une copie, le client doit signer l'original. Il lui envoie donc l'original (passage par reference) et apres avoir ete signé, le contrat reprend sa place originale dans le tiroir.
 
Troisieme situation, passage par reference constante:
le contrat est signé et ne peut plus etre modifié, par contre le client demande a voir l'original pour etre sur de la clause XXX. Le commercial A va donc devoir recuperer l'original mais il le laisse sous enveloppe plastifiée pour que le client ne puisse pas faire des ajouts ou des modifications. Evidemment un client malhonnete pourrait tres bien enlever l'enveloppe plastique et faire ses modifs sur le contrat original mais il s'expose a des poursuites (plantage) ou au fait qu'on lui ait passé une copie de l'original sans lui dire, copie qui va etre détruite immédiatement apres.
 
Quatrieme situation, passage par pointeur:
Un employé C est chargé de faire une liste de tous les contrats de la boite, il demande donc a l'employé B ou il peut trouver le contrat. L'employé B lui repond "4eme armoire 2e tiroir". Cela suffit a l'employé C qui l'inscrit dans sa liste.
Peu apres, l'employé C va chercher directement le contrat dans son emplacement puisqu'il a son adresse et va faire des modifs dessus. Puis il prend egalement le contrat du troisieme tiroir, du quatrieme etc.. (arithmetique des pointeurs).
Par contre cela arrive que l'employé B, le petit malin, ait déplacé les contrats et donc que l'adresse qu'il a donné a C, n'est plus valable (invalid pointer). Ou que l'employé C, trop curieux aille jusqu'au dixieme tiroir, et il touche a un contrat qu'il n'aurait pas du modifier (dépassement de tableau).
 
A+
LeGreg

Reply

Marsh Posté le 05-06-2002 à 16:43:13    

Moi je dis :jap:

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed