Ik weet dat referenties syntactische suiker zijn, zodat code makkelijker te lezen en te schrijven is.
Maar wat zijn de verschillen?
Samenvatting van antwoorden en links hieronder:
NULL
), terwijl een reference altijd naar een object verwijst.&obj + 5
).Om een misverstand uit de weg te ruimen:
De C++ standaard is heel voorzichtig om niet te dicteren hoe een compiler referenties mag implementeren, maar elke C++ compiler implementeert referenties als pointers. Dat wil zeggen, een declaratie zoals:
int &ri = i;
als het niet helemaal weg geoptimaliseerd is, alloceert dezelfde hoeveelheid opslag als een pointer, en plaatst het adres van
i
in die opslag.
Dus, een pointer en een reference gebruiken beiden dezelfde hoeveelheid geheugen.
Als een algemene regel,
Interessant om te lezen:
Een pointer kan opnieuw worden toegewezen:
int x = 5;
int y = 6;
int *p;
p = &x;
p = &y;
*p = 10;
assert(x == 5);
assert(y == 10);
Een referentie kan niet, en moet worden toegewezen bij initialisatie:
int x = 5;
int y = 6;
int &r = x;
Een pointer heeft zijn eigen geheugenadres en grootte op de stack (4 bytes op x86), terwijl een reference hetzelfde geheugenadres deelt (met de originele variabele) maar ook wat ruimte op de stack inneemt. Aangezien een verwijzing hetzelfde adres heeft als de oorspronkelijke variabele zelf, is het veilig om een verwijzing te zien als een andere naam voor dezelfde variabele. Opmerking: waar een pointer naar wijst kan zich op de stack of heap bevinden. Hetzelfde geldt voor een referentie. Mijn bewering in deze verklaring is niet dat een pointer naar de stack moet wijzen. Een pointer is gewoon een variabele die een geheugenadres bevat. Deze variabele staat op de stack. Aangezien een verwijzing zijn eigen ruimte op de stack heeft, en aangezien het adres hetzelfde is als de variabele waarnaar het verwijst. Meer over stack vs heap. Dit impliceert dat er een echt adres van een referentie is dat de compiler je niet zal vertellen.
int x = 0;
int &r = x;
int *p = &x;
int *p2 = &r;
assert(p == p2);
Je kunt pointers hebben naar pointers naar pointers die extra niveaus van indirection bieden. Terwijl referenties slechts één niveau van indirectie bieden.
int x = 0;
int y = 0;
int *p = &x;
int *q = &y;
int **pp = &p;
pp = &q;//*pp = q
**pp = 4;
assert(y == 4);
assert(x == 0);
Pointer kan direct nullptr
toegewezen worden, terwijl reference dat niet kan. Als je hard genoeg je best doet, en je weet hoe, kun je het adres van een verwijzing nullptr
maken. Op dezelfde manier, als je hard genoeg je best doet, kun je een verwijzing naar een pointer hebben, en dan kan die verwijzing nullptr
bevatten.
int *p = nullptr;
int &r = nullptr; <--- compilatiefout
int &r = *p; <--- waarschijnlijk geen compilatiefout, zeker niet als de nullptr verborgen zit achter een functie-aanroep, maar toch verwijst naar een niet-bestaande int op adres 0
Pointers kunnen itereren over een array, je kunt ++
gebruiken om naar het volgende item te gaan waar een pointer naar wijst, en + 4
om naar het 5e element te gaan. Dit maakt niet uit hoe groot het object is waar de pointer naar wijst.
Een pointer moet gederefereerd worden met *
om toegang te krijgen tot de geheugenlocatie waar hij naar wijst, terwijl een reference direct gebruikt kan worden. Een pointer naar een klasse/structuur gebruikt ->
om toegang te krijgen tot zijn leden, terwijl een verwijzing een .
gebruikt.
Een pointer is een variabele die een geheugenadres bevat. Ongeacht hoe een verwijzing is geïmplementeerd, heeft een verwijzing hetzelfde geheugenadres als het item waarnaar het verwijst.
Referenties kunnen niet in een array worden gepropt, terwijl pointers dat wel kunnen (Bewaard door gebruiker @litb)
Const referenties kunnen gebonden worden aan temporaries. Pointers niet (niet zonder enige indirection):
const int &x = int(12); //legaal C++
int *y = &int(12); //illegaal om een tijdelijke te dereferenten.
Dit maakt const&
veiliger voor gebruik in argument-lijsten enzovoort.
Afgezien van syntactische suiker, is een verwijzing een const
pointer (niet pointer naar een const
). Je moet bepalen waarnaar het verwijst wanneer je de referentie variabele declareert, en je kunt het later niet veranderen.
Update: nu ik er wat meer over nadenk, is er een belangrijk verschil.
Een const pointer's target kan vervangen worden door zijn adres te nemen en een const cast te gebruiken.
Een reference's target kan op geen enkele manier vervangen worden, behalve door UB.
Dit zou de compiler in staat moeten stellen om meer optimalisatie op een verwijzing uit te voeren.