&Referenz und *Pointer



  • Eine Referenz "zeigt" während ihrer gesamten Lebenszeit auf genau EIN Objekt (und es ist aus C++ Sicht auch nicht möglich, an dieser Verbindung etwas zu ändern). Ein Zeiger kann beliebig umgebogen werden (oder auf NULL gesetzt). Außerdem kannst du mit Referenzen keine Adress-Arithmetik betreiben.

    @const: ein 'const Test&' ist eine Referenz auf ein konstantes Objekt - bei dem kannst du die Methoden getA() und getB() nicht verwenden, weil sie nicht als const gekennzeichnet sind.

    class Test
    {
    public:
        ...    
        int getA() /*hier:*/ const
        {
            return a;
        }
        ...
    };
    

    Edit: @TLEP: Aus C++ Sicht sind Referenzen "nur" ein Alias für eine andere Variable. Aber der Compiler muß das auch auf eine Art darstellen, die dein Rechner versteht - und wenn der keine eingebauten Referenzen hat, werden dafür hinter den Kulissen wieder Zeiger verwendet.



  • Ahhh okay, dann hab ich das mit const schonmal verstanden 🙂

    Das andere noch nicht ganz - okay, daß Pointer Variablen sind und Referenzen die Adressen ist mir eigentlich klar, aber in welchen Fällen spricht es dann dafür, tatsächlich eine Referenz zu verwenden und nicht einfach einen Pointer (was ich bisher eigentlich grundsätzlich gemacht habe)?



  • Ich hatte immer gedacht, dass wenn man mit einer Referenz arbeitet, genau mit dem Objekt arbeit, wo die Referenz "draufzeigt". Also das nicht mit einem Zieger auf das Objekt, sonder mit dem Objekt selbst.
    Frage: Wenn man eine Referenz als Parameter einer Funktion implementiert, werden die Parameter noch auf den Stack gepusht? Würde ja eigentlich keinen Sinn machen.



  • Naja eigentlich muß das schon passieren, schließlich weiß die Funktion ja sonst nicht, welches Objekt sie benutzen soll. Du kannst ja trotz allem die Funktion mit zig verschiedenen Objekten aufrufen, daher muß sie zumindest die Adresse haben.



  • Wenn du sicher sein willst/bist, daß immer eine gültige Variable hinter dem Verweis steckt, nimmst du lieber eine Referenz (das ist in C++ wohl häufiger der Fall - gerade bei Funktionsparametern).

    Pointer solltest du nur verwenden, wenn in einer Situation keine Referenzen nutzbar sind:

    • das Ziel des Verweises kann sich während seiner Lebenszeit ändern (Anmerkung: das betrifft übrigens keine Funktionsparameter, die bei jedem Aufruf woanders hinzeigen könnten)
    • du brauchst eine Möglichkeit, auf "nichts" zu verweisen (es gibt keine NULL-Referenzen
    • hinter dem Verweis steckt kein einzelnes Objekt, sondern ein komplettes Array

    (btw, ein häufiges Anwendungsfeld von Pointern ist dynamische Speicherverwaltung)



  • Hallo,
    irgendwie sind Referenzen bisher spurlos an mir vorbeigegangen(Außer bei Funktionparametern)
    In folgendem Code bspw. hätte ich wahrscheinlich eher ne Face-Referenz als nen Face-Pointer verwenden sollen oder ?
    Der Code ist einfach nur aus einem größeren Zusammenhang ausgeschnitten, also bitte nicht den Sinn hinterfragen. 😃

    for(unsigned int i = 0; i< a.adjacentFaces.size();i++){
        Face *myFace = &FaceMap[a.adjacentFaces[i]];
    	if(a.index == myFace->x){
    		if(b.index == myFace->y || b.index == myFace->z){
    		FaceMap.erase(i);
    		}
    		else{
    		myFace->x = b.index;
    		}
            }
    }
    


  • CStoll schrieb:

    Edit: @TLEP: Aus C++ Sicht sind Referenzen "nur" ein Alias für eine andere Variable. Aber der Compiler muß das auch auf eine Art darstellen, die dein Rechner versteht - und wenn der keine eingebauten Referenzen hat, werden dafür hinter den Kulissen wieder Zeiger verwendet.

    Nicht unbedingt. In folgendem Code z.B. würde ich erwarten (ungetestet), dass der Compiler bitte *keinen* Zeiger anlegt:

    {
        int a = 5;
        int& ra = a;
        ra = 6;
    }
    

    Hier einen Zeiger anzulegen ist ein vollkommen unnützes Overhead, 'ra' ist hier ein echtes Alias und der Compiler wird wahrscheinlich für 'ra' dasselbe Symbol wie für 'a' ausspucken und die Initialisierung von 'ra' entfernen.

    (Sobald eine neue Stack Frame angelegt wird, geht das natürlich nicht mehr, da muss ein Zeiger erzeugt werden.)



  • Blue5teel schrieb:

    ...
    In folgendem Code bspw. hätte ich wahrscheinlich eher ne Face-Referenz als nen Face-Pointer verwenden sollen oder ? ...

    Naja, das ist ja ein klassisches Beispiel dafür, dass Du eigentlich einen "Alias" (abkürzende Bezeichnung für FaceMap[a.adjacentFaces[i]]) verwenden möchtest. Und genau dafür sind Referenzen ideal.
    Mit dem Pointer läufst Du Gefahr, ihn im Code versehentlich "umzubiegen" (auf ein Anderes Objekt oder 0) oder nicht zu wissen, ob Du irgendwas "deleten" musst oder nicht. Besonders über verschiedene Call-Ebenen hinweg wird das schnell zum Problem (z.B. musst Du dann eigentlich immer auf 0 überprüfen).
    Das alles sparst Du Dir halt mit einer Referenz.

    Gruß,

    Simon2.



  • TLEP schrieb:

    Frage: Wenn man eine Referenz als Parameter einer Funktion implementiert, werden die Parameter noch auf den Stack gepusht? Würde ja eigentlich keinen Sinn machen.

    Das Problem ist doch: was pusht man auf den Stack? Das komplette Objekt? Dann hätte man plötzlich eine Kopie. Man muss also einen Verweis auf das Objekt pushen. Nur welche Möglichkeiten hat man dabei? Man muss eben einen Zeiger auf das Objekt pushen.



  • Konrad Rudolph schrieb:

    CStoll schrieb:

    Edit: @TLEP: Aus C++ Sicht sind Referenzen "nur" ein Alias für eine andere Variable. Aber der Compiler muß das auch auf eine Art darstellen, die dein Rechner versteht - und wenn der keine eingebauten Referenzen hat, werden dafür hinter den Kulissen wieder Zeiger verwendet.

    Nicht unbedingt. In folgendem Code z.B. würde ich erwarten (ungetestet), dass der Compiler bitte *keinen* Zeiger anlegt:

    {
        int a = 5;
        int& ra = a;
        ra = 6;
    }
    

    Hier einen Zeiger anzulegen ist ein vollkommen unnützes Overhead,

    deswegen wird ein compiler keinen zeiger anlegen, genausowenig wie er das bei

    {
        int a = 5;
        int* ra = &a;
        *ra = 6;
    }
    

    machen wird.



  • Fangt bloß nicht wieder damit an, ob Referenzen speicher belegen oder nicht, dass hatten wir schon alles ausführlich hier 😉 :
    http://c-plusplus.net/forum/viewtopic-var-p-is-1293753.html#1293753

    "Nicht spezifiziert", aber wir können davon ausgehen, dass die meißten Compiler es so machen: http://c-plusplus.net/forum/viewtopic-var-p-is-1330752.html#1330752 ( als Aliase bzw. zweiter Name )


Anmelden zum Antworten