Referenzen bei Variablen?



  • also den selben Pointer haben

    Von der eigentlichen Variable kannst Du eine "Adresse" erfragen und in einem Pointer abspeichern: pa = &a
    Geht dies auch bei der C++-Referenz? 😉

    In der Tat:

    #include <iostream>
    #include <conio.h>
    using namespace std;
    
    int main()
    {
        int a=42;
        int& b = a;
        int* pa = &a;
        int* pb = &b;
    
        cout << b << " " << pa << " " << pb;
    
        getch();
    }
    

    42 0x22ff74 0x22ff74

    Gute Erklärung!



  • eigentlich unterscheiden sich pointer und referezen nicht groß in der benutzung. denn beides brauch man!

    ich hab die erfahrung gemacht, dass pointer sich super eignen wen du auf etwas ZEIGEN willst 😉 und referenzen zB bei rückgabe werten oder übergaben..

    bsp:
    du baust dir einen eigenen datentyp. dann erhalten die methoden dieses datentyps "immer" eine referenz auf diesen typen. die faustregel sollte sein: standard typen wie int, float, char, string kopiert man bei der übergabe und eigene typen als rederenz. und genau so bei der rückgabe...



  • Man sollte "eigentlich" immer auf referenzen zurückgreifen... pointer sollte man verwenden, wenn der wert NULL sein kann.

    //Referenz
    class foo{
    
    int &m_i;
    
    foo(int &i) : (m_i(i){}
    
    }
    
    //Pointer
    class bar{
    
    int *m_i;
    
    bar(int &i) : (m_i(&i){}
    
    }
    

    das problem bspw. hierberi, muss du zwangläufig einen Default Kosntruktor implementieren (für einsatz von stl containern), ist das bei "foo" nicht möglich, da die membervariable als referenz auf eine übergeben zeigen muss.. und nicht NULL sein kann.. bei bar könnte ich den pointer immerhin auf 0 setzen...#

    ein kleiens beispiel...



  • BorisDieKlinge schrieb:

    Man sollte "eigentlich" immer auf referenzen zurückgreifen... pointer sollte man verwenden, wenn der wert NULL sein kann.

    Wenn ich mit richtig erinnere verwendet z.B. Qt konsequent Pointer mit der Begründung, das man dann auch direkt erkennt das mit dem Original Objekt gearbeitet wird und nicht einer Kopie.



  • pospiech schrieb:

    ...
    Wenn ich mit richtig erinnere verwendet z.B. Qt konsequent Pointer mit der Begründung, das man dann auch direkt erkennt das mit dem Original Objekt gearbeitet wird und nicht einer Kopie.

    🙄 Also diese Begründung halte ich für ziemlich dämlich.
    Das kann nur jemand geschrieben haben, der nicht viel Erfahrung mit Referenzen hat (weswegen ich ihn insgesamt für nicht allzu berufen halte, C++-Programmiertechniken zu bewerten oder Designentscheidungen zu treffen).
    (nur zur Klarstellung: Mir ist durchaus bewusst, dass das kein statement von dir/pospiech ist).

    Gruß,

    Simon2.



  • @simon: muss ich mich angegriffen fühlen?



  • Macht es denn Performance mäßig einen Unterschied ob man einen Pointer oder eine Referenz übergibt?



  • naja nicht unbedingt, allerdings geht bischen zeit drauf wenn du den zeiger derefenzieren musst...



  • BorisDieKlinge schrieb:

    @simon: muss ich mich angegriffen fühlen?

    Also von mir nicht!
    Ich teile Deine Einschätzung: Referenzen sind was Feines!

    Du bist nur "aus historischen Gründen" in das Zitat gerutscht (ich mach' Dich da mal raus).

    Gruß,

    Simon2.


  • Mod

    BorisDieKlinge schrieb:

    Man sollte "eigentlich" immer auf referenzen zurückgreifen... pointer sollte man verwenden, wenn der wert NULL sein kann.

    //Referenz
    class foo{
    
    int &m_i;
    
    foo(int &i) : (m_i(i){}
    
    }
    
    //Pointer
    class bar{
    
    int *m_i;
    
    bar(int &i) : (m_i(&i){}
    
    }
    

    das problem bspw. hierberi, muss du zwangläufig einen Default Kosntruktor implementieren (für einsatz von stl containern), ist das bei "foo" nicht möglich, da die membervariable als referenz auf eine übergeben zeigen muss.. und nicht NULL sein kann.. bei bar könnte ich den pointer immerhin auf 0 setzen...#

    ein kleiens beispiel...

    Wieso aus der Tatsache, dass Zeiger auch 0 sein können, folgt, dass man sie dann nicht verwenden sollte, wenn 0 kein sinnvoller Ausgangswert ist, erschließt sich mir nicht. Generell sehe ich im Falle nicht-statischer Member keinen Vorteil, den Referenzen gegenüber konstanten Zeiger haben könnten (ignorieren wir mal den pathologischen Fall eines defekten &-Operators). Nachteile dagegen sind offensichtlich: da Referenzen keine Objekte sind, kann man nicht mit Zeigern auf Member auf sie verweisen. Abgesehen davon hat man dann auch den seltsamen Fall, dass sizeof(member1)+sizeof(member2)+... > sizeof(Klasse) gelten kann.
    Da man in vielen Fällen tatsächlich eine Wahl hat zwischen Zeigern und Referenzen sollte man generell die Form wählen, die die Intention des Programmierers besser ausdrückt, und sich nicht mit irgendwelchen vermeintlichen oder unwesentlichen technischen Unterschieden aufhalten. Wenn ich ein Alias brauche, nutze ich Referenzen - das die Objekte auch eine Adresse haben, ist in dem Moment völlig irrelevant - hat die Adresse selbst einen "Wert" für mich, benutze ich Zeiger (die selbe Argumentation bestimmt dann auch die Form evtl. nötiger casts). Natürlich spielen technische Fragen in bestimmten Fällen ebenfalls eine Rolle.



  • BorisDieKlinge schrieb:

    naja nicht unbedingt, allerdings geht bischen zeit drauf wenn du den zeiger derefenzieren musst...

    diese kosten hast du bei referenzen aber auch.



  • pospiech schrieb:

    Macht es denn Performance mäßig einen Unterschied ob man einen Pointer oder eine Referenz übergibt?

    BorisDieKlinge schrieb:

    naja nicht unbedingt, allerdings geht bischen zeit drauf wenn du den zeiger derefenzieren musst...

    Das glaub ich nicht.
    Die Referenz muss genauso dereferenziert werden, das geschieht nur implizit.

    Die Funktionen

    void assign_5_ref( int &r ) { r = 5; }
    void assign_5_ptr( int *p ) { *p = 5; }
    

    würden den gleichen Maschinencode erzeugen.

    Referenzen können im Vergleich zu Pointern die Performance steigern:
    Dass ihnen nur einmal ein Objekt zugewiesen werden kann (normalerweise), kann dem Compiler bei der Optimierung helfen.

    int &x;
    ist also nicht gleichbedeutend mit
    int *x;
    sondern mit
    int * const x;

    Allerdings hat const kaum noch Stellenwert.
    Lediglich bei statischen/globalen Variablen (die soll man eh nicht benutzen) tun sich noch manche Compiler noch schwer. ( auch VCpp )

    Bleibt also nur noch, dass bei Referenzen die Prüfung auf NULL oder andere Ausnahmewerte wegfällt.

    //edti: -.- wieder zu langsam.



  • Ich denke, dass beide ihre Berechtigung haben. Eine Referenz ist lediglich ein "verkappter" Zeiger. Was ich wirklich grausig finde bei C/C++, ist die Tatsache, dass die gleichen Zeichen (&,*) für völlig verschiedene Dinge verwendet werden. Das schafft bei Anfängern/Umsteigern wohl die größten Probleme und ist m.E. ein echter Schwachpunkt von C/C++. 🙄


Anmelden zum Antworten