Condiție preliminară: Indicatori , Referințe
C și C++ suportă pointeri, care este diferit de majoritatea altor limbaje de programare, cum ar fi Java, Python, Ruby, Perl și PHP, deoarece acceptă doar referințe. Dar, interesant, C++, împreună cu pointerii, acceptă și referințe.
La suprafață, atât referințele, cât și pointerii sunt foarte similare, deoarece ambele sunt folosite pentru ca o variabilă să ofere acces la alta. Având în vedere că ambele oferă multe aceleași capacități, este adesea neclar care este diferența dintre aceste mecanisme. În acest articol, voi încerca să ilustrez diferențele dintre indicatori și referințe.
Indicatori : Un pointer este o variabilă care deține adresa de memorie a unei alte variabile. Un pointer trebuie dereferențiat cu * operator pentru a accesa locația de memorie către care indică.
Referințe : O variabilă de referință este un alias, adică un alt nume pentru o variabilă deja existentă. O referință, ca un pointer, este, de asemenea, implementată prin stocarea adresei unui obiect.
O referință poate fi gândită ca un pointer constant (a nu se confunda cu un pointer către o valoare constantă!) cu indirectare automată, adică compilatorul va aplica * operator pentru tine.
int i = 3; // A pointer to variable i or 'stores the address of i' int *ptr = &i; // A reference (or alias) for i. int &ref = i;>
Diferențele :
1. Inițializare: Un pointer poate fi inițializat în acest fel:
int a = 10; int *p = &a; // OR int *p; p = &a;>
Putem declara și inițializa pointerul la același pas sau pe mai multe linii.
2. În timpul referințelor,
int a = 10; int &p = a; // It is correct // but int &p; p = a; // It is incorrect as we should declare and initialize references at single step>
NOTĂ: Această diferență poate varia de la compilator la compilator. Diferența de mai sus este în ceea ce privește Turbo IDE.
3. Reatribuire: Un pointer poate fi reatribuit. Această proprietate este utilă pentru implementarea structurilor de date precum o listă legată, un arbore etc. Vezi următorul exemplu:
int a = 5; int b = 6; int *p; p = &a; p = &b;>
4. Pe de altă parte, o referință nu poate fi reatribuită și trebuie alocată la inițializare.
int a = 5; int b = 6; int &p = a; int &p = b; // This will throw an error of 'multiple declaration is not allowed' // However it is valid statement, int &q = p;>
5. Adresa de memorie: Un pointer are propria sa adresă de memorie și dimensiune pe stivă, în timp ce o referință partajează aceeași adresă de memorie cu variabila originală și nu ocupă spațiu pe stivă.
int &p = a; cout << &p << endl << &a;>
6. Valoare NULL: Un pointer poate fi atribuit direct NULL, în timp ce o referință nu poate fi. Constrângerile asociate referințelor (fără NULL, fără reatribuire) asigură că operațiunile subiacente nu se confruntă cu o situație de excepție.
7. Direcție: Puteți avea un pointer la pointer (cunoscut sub numele de indicator dublu) care oferă niveluri suplimentare de indirectare, în timp ce referințele oferă doar un nivel de indirectare. De exemplu,
In Pointers, int a = 10; int *p; int **q; // It is valid. p = &a; q = &p; // Whereas in references, int &p = a; int &&q = p; // It is reference to reference, so it is an error>
8. Operatii aritmetice: Diverse operații aritmetice pot fi efectuate pe pointeri, în timp ce nu există așa ceva numit Aritmetica de referință (cu toate acestea, puteți efectua aritmetica pointer pe adresa unui obiect indicat de o referință, ca în &obj + 5).
Forma tabelară a diferenței dintre referințe și pointeri în C++
| Referințe | Indicatori | |
|---|---|---|
| Reatribuire | Variabila nu poate fi reatribuită în Referință. | Variabila poate fi reatribuită în Pointers. |
| Adresa de memorie | Are aceeași adresă ca variabila originală. | Pointerii au propria lor adresă de memorie. |
| Muncă | Se referă la o altă variabilă. | Stochează adresa variabilei. |
| Valoare nulă | Nu are valoare nulă. | Poate avea valoare atribuită ca nulă. |
| Argumente | Această variabilă este referită prin metoda pass by value. | Pointerul funcționează prin metoda cunoscută sub numele de trecere prin referință. |
Când să folosiți Ce
Performanțele sunt exact aceleași ca referințele sunt implementate intern ca pointeri. Dar totuși, puteți păstra câteva puncte în minte pentru a decide când să utilizați ce:
- Utilizați referințe:
- În parametrii funcției și tipurile de returnare.
- Folosește indicatori:
- Dacă este necesară aritmetica pointerului sau trecerea unui pointer NULL. De exemplu, pentru matrice (Rețineți că accesarea unei matrice este implementată folosind aritmetica pointerului).
- Pentru a implementa structuri de date precum o listă legată, un arbore etc. și algoritmii acestora. Acest lucru se datorează faptului că, pentru a indica celule diferite, trebuie să folosim conceptul de pointeri.
Citat în C++ FAQ Lite : Folosiți referințe când puteți și indicatori când trebuie. Referințele sunt de obicei preferate față de indicatoare ori de câte ori nu aveți nevoie de relocare. Acest lucru înseamnă de obicei că referințele sunt cele mai utile în interfața publică a unei clase. Referințele apar de obicei pe pielea unui obiect, iar indicatoarele în interior.
Excepția de la cele de mai sus este cazul în care parametrul unei funcții sau valoarea returnată necesită o referință sentinelă - o referință care nu se referă la un obiect. Acest lucru se face, de obicei, cel mai bine prin returnarea/luarea unui pointer și acordând valorii nullptr această semnificație specială (referințele trebuie întotdeauna să numească obiecte, nu un pointer nul dereferențiat).
Articol înrudit:
Când trecem argumentele ca referință sau indicatori?