Hva er forskjellene mellom en pekervariabel og en referansevariabel i C++?

Jeg vet at referanser er syntaktisk sukker, så koden er lettere å lese og skrive.

Men hva er forskjellene?


Sammendrag fra svar og lenker nedenfor:

  1. En peker kan tilordnes på nytt et hvilket som helst antall ganger, mens en referanse ikke kan tilordnes på nytt etter binding.
  2. Pekere kan ikke peke noe sted (NULL), mens en referanse alltid refererer til et objekt.
  3. Du kan ikke ta adressen til en referanse slik du kan med pekere.
  4. Det er ingen "referansearitmetikk" (men du kan ta adressen til et objekt som pekes av en referanse og gjøre pekeraritmetikk på den som i "obj + 5").

For å avklare en misforståelse:

  • C ++ -standarden er veldig forsiktig med å unngå å diktere hvordan en kompilator kan implementere referanser, men hver C++-kompilator implementerer referanser som pekere. Det vil si en erklæring som:*

int &ri = i;

hvis den ikke er optimalisert helt bort, allokerer samme mengde lagringsplass som en peker, og plasserer adressen av i inn i den lagringen.

Så, en peker og en referanse bruker begge den samme mengden minne.

Som en generell regel,

  • Bruk referanser i funksjonsparametere og returtyper for å gi nyttige og selvdokumenterende grensesnitt.
  • Bruk pekere for å implementere algoritmer og datastrukturer.

Interessant lesning:

  1. En peker kan tildeles på nytt:

    int x = 5;
    int y = 6;
    int *p;
    p = &x;
    p = &y;
    *p = 10;
    assert(x == 5);
    assert(y == 10);

    En referanse kan ikke, og må tilordnes ved initialisering:

    int x = 5;
    int y = 6;
    int &r = x;
  2. En peker har sin egen minneadresse og størrelse på stakken (4 byte på x86), mens en referanse deler samme minneadresse (med den opprinnelige variabelen), men tar også litt plass på stakken. Siden en referanse har samme adresse som den opprinnelige variabelen selv, er det trygt å tenke på en referanse som et annet navn for den samme variabelen. Merk: Hva en peker peker til kan være på stakken eller bunken. Ditto en referanse. Min påstand i denne uttalelsen er ikke at en peker må peke til stakken. En peker er bare en variabel som holder en minneadresse. Denne variabelen er på stabelen. Siden en referanse har sin egen plass på stakken, og siden adressen er den samme som variabelen den refererer til. Mer om [stack vs heap][1]. Dette innebærer at det er en reell adresse til en referanse som kompilatoren ikke vil fortelle deg.

    int x = 0;
    int &r = x;
    int *p = &x;
    int *p2 = &r;
    assert(p == p2);
  3. Du kan ha pekere til pekere til pekere som tilbyr ekstra nivåer av indirekte henvisning. Mens referanser bare tilbyr ett nivå av indirekte henvisning.

    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);
  4. Peker kan tildeles nullptr direkte, mens referanse ikke kan. Hvis du prøver hardt nok, og du vet hvordan, kan du gjøre adressen til en referanse nullptr. På samme måte, hvis du prøver hardt nok, kan du ha en referanse til en peker, og da kan den referansen inneholde nullptr.

    int *p = nullptr;
    int &r = nullptr; 
Kommentarer (43)

Bortsett fra syntaktisk sukker er en referanse en const-peker (ikke peker til en const). Du må fastslå hva den refererer til når du deklarerer referansevariabelen, og du kan ikke endre den senere.

Oppdatering: nå som jeg tenker litt mer på det, er det en viktig forskjell.

En const peker&# 39s mål kan erstattes ved å ta adressen og bruke en const cast.

En referanses mål kan ikke erstattes på noen annen måte enn UB.

Dette skal tillate kompilatoren å gjøre mer optimalisering på en referanse.

Kommentarer (5)

En referanse kan aldri være NULL.

Kommentarer (10)