Unterschied: Referenz& und *Pointer



  • hallo

    ich habe bisher meistens nur ansi c programiert,
    möchte jetz gerne wissen,
    was der Unterschied zwischen einer Referenz ist und einem Pointer

    als beispiel:
    was ist genau der unterschied zwischen

    int meineFunktion(int& bla) und
    int meineFunktion(int *bla) ?

    ich mein warum sollte cpp ein & einführen, wenn es das gleiche wäre wie ein pointer ... ?

    in cpp findet es oft anwendung bei zeiger auf objekten
    (myclass& obj)
    z.b.

    aber wo liegt jetz genau der unterschied ?

    könnte ich auch nich schreiben (myclass *obj) , habs zwar noch nich probiert, aber das erscheint mir auf den ersten blick noch eher verständlicher...

    würde mich für einen ausführliche bericht freuen 😉

    mfg haMMer



  • ja referenzen sind pointer ähnlich,
    einer der gründe wieso es sie gibt ist das man mit ihrer hilfe operatoren überladen kann
    ein ander das sie theoretisch (wenn man es drauf anlegt kann man auch das hinkrigen) nie NULL oder wild sein können



  • also kann man auch myclass *obj schreiben ?

    das wäre ja dann nur ne c++ vereinfachung

    [ Dieser Beitrag wurde am 28.03.2003 um 10:55 Uhr von Hammer editiert. ]



  • hi

    und wenn du referenzen verwendest fällt innerhalb der funktion dieses "dereferenzieren" weg was du immer mit pointern machen musst wenn du ihnen einen wert zuweisen möchtest...und bei der parameterübergabe musst du nicht mehr den &operator verwenden wie bei pointern...

    bye

    apo



  • Du kannst auch weiterhin mit Zeigern Arbeiten.

    void foo1(int * a)
    {
      if(a == NULL)
        return;
      a = 12;
    }
    ;
    
    void foo2(int & a)
    {
      a = 12;
    }
    
    int a;
    foo1(&a);
    foo2(a);
    

    Besonders Interesannt wird es wenn Du einen Wert nur zum lesen haben willst.

    foo(const MyObj & a);
    
    MyObj a;
    foo(a);
    

    Der Anwender von foo muss sich nicht mit Zeigern rumschlagen. Er übergibt a einfach. Zudem musst Du bei Zeigern ja auf NULL prüfen, bei Referenzen fällt das weg da Referenzen immer auf etwas zeigen müssen.



  • Rückschluss:

    also es besteht wohl kein wehsentlicher unterschied zwischen pointern und referenzen , ausser dass pointer dereferenziert werden müssen und man bei referenzen sich viel schreibarbeit spart, was die übergabe betrifft, im sinne einer art vereinfachung von c++. intern arbeiten beide gleich...



  • Eine Referenz kann aber nie auf NULL zeigen, im Gegensatz zu einem Zeiger.



  • Hammer: Genau, aber nicht nur Schreibarbeit. Ohne Referenzen müßte man zb bei einem überladenen Zuweisungsoperator sowas schreiben: a = &b; was die ganze Sache nicht mehr ganz so sinnvoll macht ...



  • void foo1(int * a)
    {
    if(a == NULL)
    return;
    a = 12;
    }

    das muss:

    void foo1(int * a)
    {
      if(*a == NULL)
        return;
      *a = 12;
    }
    

    heissen ...



  • Referenzen schützen nicht vor Nullpointern! Es ist lediglich undefiniert, was bei folgendem Programm passiert:

    void foo(int &a) {
      if (&a)
        a = 12;
    }
    
    int main() {
      int *p = 0;
      foo(*p);
    }
    

    GCC schluckt das anstandslos ...



  • Original erstellt von Dimah:
    ...nie NULL oder wild sein können

    void func(int&);
    int* pInt;
    int& rInt = *pInt;
    func(rInt);
    

    Und ich glaube das ist gar nicht so unrealistisch das eine Referenz mal ausversehen durch fehlerhaften Code auf bereits freigegeben Spicher o.ä. zeigt.



  • Referenzen schützen nicht vor Nullpointern!

    Naja, auf Semantikebene schon. Ein Refernz-Parameter deutet an, dass die Funktion immer einen gültiger Wert erwartet. Ein Pointer-Parameter zeigt an, dass auch ein "sentinel value" (wer kennt eine schöne deutsche Übersetzung?) in Form des Nullzeigers möglich ist.

    void foo(int &a) {
    if (&a)
    a = 12;
    }

    int main() {
    int *p = 0;
    foo(*p);
    }

    Wer sowas macht hat pech gehabt. So wie ich den Standard lese, gibt es keine Möglichkeit für foo die Situation zu retten, da das Kind bereits vorher in den Brunnen gefallen ist.



  • Also zwischen Pointern und Referencen gibt es auf jeden Fall einen Unterschied, mir fallen die zwar jetzt alle nicht ein, aber ich hab das auch mal gewusst.

    Das da genauso Fehler auftreten koennen, wenn ich da wild irgendwelche Pointer reinhaue oder sonst irgendwas mach ist ja wohl auch klar, aber wenn ich das benutze wie bei call by value dann sollte es eigentlich keine Fehler machen.

    Dann kann man Referencen auch const machen f(const int& i) was ja bei Pointer nicht geht.



  • Dann kann man Referencen auch const machen f(const int& i) was ja bei Pointer nicht geht.

    foo(const int * pi) /* lalala */
    


  • foo(const int * const pi) /* lalala */

    so gehts doch? 😕 😕



  • ich sag ja das das lange her ist



  • Dann kann man Referencen auch const machen

    Nö. In C++ sind alle Referenzen const. Ein explizites const für eine Referenz ist verboten.
    Also:
    Es gibt Referenzen (implizit const) (Bsp: int&)
    Es gibt Referenzen auf const (Bsp: int const&)
    Es gibt Zeiger (Bsp: int*)
    Es gibt Zeiger auf const (Bsp: int const*)
    Es gibt const Zeiger (Bsp: int const)
    Es gibt const Zeiger auf const. (Bsp: int const
    const)

    Es gibt keine const Referenzen (Bsp: int& const)
    Es gibt keine const Referenzen auf const.(Bsp: int const&const)

    foo(const int * const pi) /* lalala */

    Das ist genauso überflüssig wie
    foo(const int);
    und aus Überladungssicht genau das gleiche wie
    foo(const int * pi)

    Bedenke. Der Zeiger wird "by value" übergeben.

    [ Dieser Beitrag wurde am 28.03.2003 um 13:47 Uhr von HumeSikkins editiert. ]



  • Ich bin grad etwas verwirrt.
    Wäre bei

    *```cpp
    foo(const int * pi) /
    lalala */

    pi nicht ein konstanter Zeiger, sprich der Wert von pi wäre const?
    Imho wäre dann bei

    foo(const int &i)
    

    das i durch die Konstante quasi ein unveränderlicher Alias der übergebenen Variable. Denn Zeiger werden ja per value übergeben und Referenzen eben nicht.
    Deswegen sollte man ja grad Referenzen verwenden, da keine Kopie angelegt wird und somit Speicher gespart und Performance gewonnen wird. Oder liege ich da falsch?



  • Ich bin grad etwas verwirrt.
    Wäre bei[quote] *```cpp
    foo(const int * pi) /
    lalala */

    pi nicht ein konstanter Zeiger, sprich der Wert von pi wäre const?
    [/QUOTE]
    ne pi ist ein nicht konstanter Zeiger (adresse die i.d.r. 4 byte braucht)(der per value übergeben wird) auf ein konstantes int,
    der wert von pi ist nicht const, der wert von pi ist irgend so eine komische speicher adresse, aber die bytes die sich an dieser speicher adresse befinden dürfen nicht geändert werden

    Imho wäre dann bei

    foo(const int &i)
    

    das i durch die Konstante quasi ein unveränderlicher Alias der übergebenen Variable. Denn Zeiger werden ja per value übergeben und Referenzen eben nicht.
    Deswegen sollte man ja grad Referenzen verwenden, da keine Kopie angelegt wird und somit Speicher gespart und Performance gewonnen wird. Oder liege ich da falsch? [/QB]

    i.d.r. werden referenzen intern über pointer implementiert



  • das ist ja das witzige: Referenzen werden immer by Value übergeben. Es gibt (noch?) keine Referenzen auf Referenzen. Auch ein Unterschied zu Zeigern.


Anmelden zum Antworten