Bonjour à tous
Quelqu'un pourrait m'expliquer s'il vous plait l'avantage que présente les réferences par apport aux pointeurs en C++
Bonjour à tous
Quelqu'un pourrait m'expliquer s'il vous plait l'avantage que présente les réferences par apport aux pointeurs en C++
Les principaux avantages sont :
Syntaxe plus simple ( ++a au lieu de ++*a ou a[2] au lieu de (*a)[2] par exemple)
On ne peut pas "déplacer" une référence par mégarde (ie la faire pointer sur autre chose) et donc moins de risques de modifier n'importe quoi...
Sémantiquement, c'est plus logique, on veut modifier une variable, on passe la vrai variable elle même, plutôt qu'une adresse de variable.
Les pointeurs, c'est plutôt les méthodes C, le C++ utilise les références qui permettent de faire à peu près tout ce que les pointeurs permettent de faire (allocation dynamique, polymorphisme, etc...)
La seule différence véritable, est au niveau des tableaux (mais pour ça, les conteneurs de la STL existent en C++) et de la "nullabilité" des pointeurs qui ne se retrouve pas chez les références (un pointeur peut ne pointer sur RIEN (être NULL), pas une référence)
Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
pensez à la balise [ code ] (bouton #) et au tag (en bas)
Merci beaucoup pour la réponse.
Je me demande est ce qu'on peut affecter un pointeur à une réference et vice verça? du moment qu'ils sont de même nature
du moment que le type de base est le même, l'affectation ne pose pas de problème :où C est une classe ou un type quelconque...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 C inst_C; C* ptr_C = &inst_C;
ici inst_C est une instance normale de la classe ou du type C.
mais comme une référence s'utilise de la même manière qu'une instance classique, il n'y a pas de problème
pour l'autre sens, c'est plus délicat, dans la mesure où l'on spécifie l'objet pointé par une référence une fois pour toute à sa création :en tous cas, une référence se manipule comme une instance normale de la classe. donc pas de problème vis-à-vis des pointeurs
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 C* ptr_C = new C; C& inst_C(*ptr_C);
Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
pensez à la balise [ code ] (bouton #) et au tag (en bas)
Bonjour,
cette question est posée toutes les semaines. aussi une simple recherche sur le forum apporte une foultitude de réponses pertinentes
http://www.developpez.net/forums/search.php
merci
Okii, la prochaine fois je le ferai promis
Mais avant j'ai un autre problème avec ces réferences Je n'arrive pas à comprendre pourquoi (dans l'exemple qui suit) on a eu recours à un autre constructeur qui admet comme argument une reference à la classe Liste, un seul constructeur ne suffirait-il pas ?? et pourquoi dans ce cas le passage par réference est devenu obligatoire ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 Liste::Liste(int t) { taille = t; adr = new float[taille]; cout<<"\nConstruction"; cout<<" Adresse de l'objet:"<<this; cout<<" Adresse de liste:"<<adr<<"\n"; } Liste::Liste(liste &v) // passage par référence obligatoire { taille = v.taille; adr = new float[taille]; for(int i=0;i<taille;i++) adr[i] = v.adr[i]; cout<<"\nConstructeur par recopie"; cout<<" Adresse de l'objet:"<<this; cout<<" Adresse de liste:"<<adr<<"\n"; } Liste::~Liste() {cout<<"\nDestruction Adresse de l'objet:"<<this; cout<<" Adresse de liste:"<<adr<<"\n"; delete adr;} void main() { cout<<"Debut de main()\n"; Liste a(3); Liste b=a; cout<<"\nFin de main()\n"; getch() ;}
Il s'agit du constructeur de copie qui permet (entre autre) de faire passer la classe "par copie" lors d'un appel de fonction..
généralement la signature est plutôt C(const C&) que C(C&)
Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
pensez à la balise [ code ] (bouton #) et au tag (en bas)
si ce n'est pas trop demandé, pourriez-vous m'expliquer ça se passe comment au juste? et dans quel cas on fait appel à un constructeur de copie?Envoyé par Swoög
L'exmple était au-dessus...Envoyé par Swoög
Le constructeur par copie est aussi très utile pour copie uné instance dans une nouvelle instance qui vient d'être déclarée.
On peut faire
Auquel cas le constructeur par copie devrait être appelé, ou aussi :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 MaClasse instance1; MaClasse instance2 = instance1;
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 MaClasse instance1; MaClasse instance2(instance1);
Ici on fait appel au constructeur par copie. Heuresement il en existe un par défaut (comme pour le constructeur normal). Tout ce qu'il fait est la recopie de toutes les données membres.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 A instanceA; A instanceB = A;
Cependant dans certain cas ce comportement n'est pas génial.
Par exemple si la classe A possède un membre int * i qui est alloué dynamiquement dans le constructeur normal.
Le constructeur par copie, pour instanceB, va recopier l'adresse et non créer une nouvelle zone en mémoire... Les deux membres des deux instances vont pointer vers le même entier...
Ce n'est pas toujours optimal, surtout quand dans le destructeur de A tu détruit cet espace mémoire, tu te retrouves à détruire deux fois la même zone.
Les références sont expliquées ici:
http://c.developpez.com/faq/cpp/?pag...CE_utilisation
Je trouve un peu léger mais bon.
Outre ce qui a été cité, les références sont surtout utiles pour éviter la programmation défensive:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 //Avec pointeur void UneFonction(int *Pointeur) { if (Pointeur == NULL) // Erreur à traiter } //Avec référence void UNeFonctionAvecReference(int &Reference) { // Le cas de test NULL n'a pas de sens, car une référence est forcemment une variable existante. } int main() { int *P=NULL; int X; int y = 10; UneFonction(P); // Grâce au test, pas de plantage, sans le test défensif, un segmentation fault dans le meilleur des cas. UneFonctionAvecReference(X) ; //Ne compile pas, X n'étant pas initialisée. UneFonctionAvecReference(X) ; //Correct, la variable est initialisée. }
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager