OVH Cloud OVH Cloud

référence ou pointeur ?

24 réponses
Avatar
Jarod
Selon vous, dans quel(s) cas est il préférable d'utiliser un pointeur et
dans quel(s) cas vaut-il mieux utiliser une référence ?
(en supposant qu'on ne veux pas faire de passage par valeur pour éviter la
copie de l'objet)
En fait, je pose cette question pour le passage d'un argument et pour la
variable d'une classe (il y a donc 2 questions).
Merci

10 réponses

1 2 3
Avatar
Andre Heinen
On Thu, 23 Jun 2005 05:53:51 +0000 (UTC), Marc Boyer
wrote:

Andre Heinen a écrit :
Si une fonction modifie son argument, certains programmeurs trouvent
qu'il vaut mieux utiliser un pointeur parce que ça rend plus explicite
(dans le code client, l'appel de fonction) le fait que la fonction
peut modifier l'argument, par exemple f(&i).


Heuh, des anciens programmeurs C alors ?


Sans doute... ;-)

D'autres programmeurs utilisent des références mais choisissent un nom
de fonction explicite, par exemple modifier(i).


Et puis en C++, on a "const" surtout.


En C aussi, maintenant. Mais const n'est visible que dans la
déclaration (et la définition) de la fonction, pas dans le code client
(l'appel de fonction).

AMHA, en C++, il vaut mieux éviter de penser pointeur <=> modif param,
car on va assez vite se faire avoir.


Personnellement, c'est aussi mon avis.

--
André Heinen
Mon e-mail, encodé ROT13: n qbg urvara ng rhebcrnayvax qbg pbz
La FAQ: http://www.cmla.ens-cachan.fr/Utilisateurs/dosreis/C++/FAQ/


Avatar
Andre Heinen
On Wed, 22 Jun 2005 22:15:30 +0200, "Pierre Lairez"
wrote:

A chaque fois que tu te le demande, utilise des références


Je ne dirais pas ça. Par exemple, je me souviens d'un temps où je me
demandais si, dans les conteneurs de la bibliothèque standard, il
valait mieux utiliser des références ou des pointeurs. Si j'avais
suivi ton raisonnement, j'aurais utilisé des références, et ça
n'aurait pas marché.

c'est plus sûr
(les références invalides n'existent pas)


J'ai dit ça aussi, une fois, mais Gaby m'a vite corrigé. Je te
recopie son exemple:

int& f() { int i = 0; return i; }
int main() { int& r = f(); return r; }

--
André Heinen
Mon e-mail, encodé ROT13: n qbg urvara ng rhebcrnayvax qbg pbz
La FAQ: http://www.cmla.ens-cachan.fr/Utilisateurs/dosreis/C++/FAQ/

Avatar
Andre Heinen
On Wed, 22 Jun 2005 16:45:07 +0200, Andre Heinen
wrote:

Une référence, une fois initialisée, ne peut plus être modifiée pour
"pointer" sur un autre objet. On ne peut pas utiliser de référence si
on a besoin de changer l'objet pointé.


Lisez plutôt "changer d'objet pointé".

--
André Heinen
Mon e-mail, encodé ROT13: n qbg urvara ng rhebcrnayvax qbg pbz
La FAQ: http://www.cmla.ens-cachan.fr/Utilisateurs/dosreis/C++/FAQ/

Avatar
kanze
Pierre Lairez wrote:
Le Tue, 21 Jun 2005 23:38:53 +0200, Jarod a écrit:

Selon vous, dans quel(s) cas est il préférable d'utiliser un
pointeur et dans quel(s) cas vaut-il mieux utiliser une
référence ?


A chaque fois que tu te le demande, utilise des références:
c'est plus sûr (les références invalides n'existent pas) et
plus pratique (parce que plus sûr, c'est autant de
vérification en moins) que des pointeurs. Donc n'utilise les
pointeurs que quand tu ne peux raisonnablement pas utiliser
les références (quand tu a beoins de réaffecter par ex.).

Je pense que cette tègle ne souffre pas d'exceptions.


void
destroy( MaClasse& c )
{
if ( ! c.canDestroy() ) {
throw CannotDestroyError ;
}
delete &c ;
}

Je connais pas mal de programmeurs qui rechigneraient à la ligne
« delete &c ». Et qui préfèreraient passer un pointeur dans ce
cas-ci.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
Marc Boyer
Andre Heinen a écrit :
On Thu, 23 Jun 2005 05:53:51 +0000 (UTC), Marc Boyer
wrote:
Andre Heinen a écrit :
D'autres programmeurs utilisent des références mais choisissent un nom
de fonction explicite, par exemple modifier(i).


Et puis en C++, on a "const" surtout.


En C aussi, maintenant. Mais const n'est visible que dans la
déclaration (et la définition) de la fonction, pas dans le code client
(l'appel de fonction).


Oui, mais le reste du langage fait qu'il est plus utile
en C++ qu'en C.
Si tu reprends mon exemple de la pile, les façons idiomatiques
de coder font que la violation du const que j'ai mondtré en C
sera moins facile en C++.

Marc Boyer
--
À vélo, prendre une rue à contre-sens est moins dangeureux
que prendre un boulevard dans le sens légal. À qui la faute ?



Avatar
moy

c'est plus sûr
(les références invalides n'existent pas)


J'ai dit ça aussi, une fois, mais Gaby m'a vite corrigé. Je te
recopie son exemple:

int& f() { int i = 0; return i; }
int main() { int& r = f(); return r; }


On peut meme creer syntaxiquement des references "nulles"
(meme si le standard dit qu'on est alors dans un cas d'
"undefined behavior"):

int main() {
int* p = 0;
int& r = *p;
return r;
}

Le compilateur ne previent pas d'un quelconque probleme,
mais a l'execution ca donne ici un "Segmentation Fault".

Yannick


Avatar
Pierre Lairez
Le Thu, 23 Jun 2005 09:44:22 +0200, Andre Heinen a
écrit:

On Wed, 22 Jun 2005 22:15:30 +0200, "Pierre Lairez"
wrote:

A chaque fois que tu te le demande, utilise des références


Je ne dirais pas ça. Par exemple, je me souviens d'un temps où je me
demandais si, dans les conteneurs de la bibliothèque standard, il
valait mieux utiliser des références ou des pointeurs. Si j'avais
suivi ton raisonnement, j'aurais utilisé des références, et ça
n'aurait pas marché.



Si la solution avec les références ne pouvait pas fonctionner, avais-tu le
choix ?


c'est plus sûr
(les références invalides n'existent pas)


J'ai dit ça aussi, une fois, mais Gaby m'a vite corrigé. Je te
recopie son exemple:

int& f() { int i = 0; return i; }
int main() { int& r = f(); return r; }



warning C4172: returning address of local variable or temporary

Bien sûr que l'on peut faire n'importe quoi, mais il ne faut pas se
plaindre après ;-).
Et une référence invalide n'existe _théoriquement_ pas. Ca veut dire que
même si ça peut arriver, ce n'est pas du ressort de celui qui reçoit la
référence. C'est à celui qui l'envoie de ne pas faire n'importe quoi. On
programme donc comme si les références invalide n'existaient pas.
D'ailleur, peux-tu tester la validité d'une référence ?


Avatar
Alexandre
Je n'ai jamais utilisé de donnée membre de type référence (je ne m'en
vante pas, c'est comme ça). Les données membres classiques de types
pointeur ne sont me semble-t-il pas transformables en références. Les
contraintes sur une donnée membre référence sont telles que les cas
d'utilisations sont certainement très spécifiques: la référence doit être
initialisée explicitement dans le constructeur, et ne pourraêtre modifiée
(l'affectation, pas l'objet référencé, bien sûr). L'objet référencé doit
donc exister avant la classe et ne pourra être détruit qu'après la
destruction de la classe.


un cas (il me semble) classique : un membre flux (ostream, par ex) qui est
donc uniquement référencé dans la classe.

class X
{
std::ostream& FluxDeSortie;
public:
X(std::ostream& Flux):FluxDeSortie(Flux);
void Print(const std::string& s) {Flux<<s;}
};

X flux_console(std::cout);
flux_console.Print("sortie sur console");
std::ofstream UnFichier("essai.txt");
X flux_fichier(UnFichier);
flux_fichier.Print("sortie sur fichier");

Avatar
Alexandre
D'ailleur, peux-tu tester la validité d'une référence ?


on ne peut pas non plus tester la validité d'un pointeur ;-) juste sa
non-nullité.

Avatar
Alexandre
Je pense que cette tègle ne souffre pas d'exceptions.


void
destroy( MaClasse& c )
{
if ( ! c.canDestroy() ) {
throw CannotDestroyError ;
}
delete &c ;
}

Je connais pas mal de programmeurs qui rechigneraient à la ligne
« delete &c ». Et qui préfèreraient passer un pointeur dans ce
cas-ci.


tout à fait, moi itou. En fait, si fondamentalement l'objet EST un pointeur,
pourquoi passer "artificiellement" une référence ?
par exemple, ceux qui utilisent C++ Builder savent que les objets VCL ne
peuvent être construits qu'avec new. Donc qu'on ne manipule que des
pointeurs. Donc passage d'un pointeur...
Et puis on peut passer un pointeur.. par référence... Exemple : on code une
fonction récursive sur un parcours d'arbre, un passe une feuille (par son
adresse) par référence (pour pouvoir faire un new dessus par exemple...)



--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


1 2 3