Zuweisungsoperator | Referenz und Zeiger



  • Hallo
    ich hätte eine Frage zum Thema Zuweisungsoperator.

    hier ist ein Beispiel:

    Vector& operator=(const Vector& other) {
       // Schutz vor Selbstzuweisung
       if (this != &other) {
          if (size != other.size) {
             delete[] values;
             if (other.size == 0) {
                values = NULL;
             } else {
                values = new type[other.size];
             }
          }
          // Daten kopieren
          size = other.size;
          copy(values , other.values , size);
       }
       return *this;
    }
    

    Frage zu Zeile 3.

    Also als Parameter bekommt der Operator eine Referenz, Referenz ist ja einfach die Speicheradresse, so wie Zeiger, nur dass man die Referenz nicht auf ein anderes Objekt "umlinken" kann. Richtig?
    Wenn also die Referenz eine Speicheradresse ist, wieso kann ich nicht gleich

    if (this != other) { // ohne &
    
    }
    

    schreiben.

    Warum muss ich vor einer Referenz zusätzlich & setzen? Liegt es daran dass man Zeiger mit Referenzen nicht direkt vergleichen kann?

    Danke schon mal.

    P.S. :schland:



  • Eine Referenz ist keine Adresse, sondern ein Aliasname für ein Objekt. Eine Referenz hat auch keine Adresse. Daher nicht direkt mit einem Zeiger vergleichbar.



  • Dit_ schrieb:

    Wenn also die Referenz eine Speicheradresse ist, wieso kann ich nicht gleich

    if (this != other) { // ohne &
    
    }
    

    schreiben.

    Warum muss ich vor einer Referenz zusätzlich & setzen? Liegt es daran dass man Zeiger mit Referenzen nicht direkt vergleichen kann?

    Genau... Du kannst Zeiger nicht mit Referenzen vergleichen.
    Du kannst ein Objekt direkt mit der Referenz vergleichen, wenn der entsprechende
    Operator definiert ist.
    Eine Referenz ist quasi ein nicht sichtbarer Zeiger, also nur das Ziel,
    wo ja das Objekt ist...

    Siehe z.B.:

    #include <iostream>
    #include <string>
    
    class A {
    public:
            A(const std::string& value) : value(value){
            }
    
            bool operator!=(const A& a){
                    return this->value != a.value;
            }
    
    private:
            std::string value;
    
    };
    
    int main()
    {
            A a("test");
            A a2("test");
    
            A* ap = &a;
            A& ar(a2);
    
            std::cout << (ap != &ar) << std::endl;
            std::cout << (*ap != ar) << std::endl;
    }
    
    1
    0
    

    Einmal werden die Speicheradressen verglichen und einmal die Objekte auf Basis des operator!=

    Gruß,
    CSpille



  • Also so wie ich das sehe, überprüfst du ob die beiden Objekte die gleichen sind, indem du die Speicheradresse vergleichst.
    Du machst ja:

    if( this != &other )
    

    Durch das this bekommst du die Adresse worauf this zeigt, sprich die Adresse deines Objektes, also des linken Operanden.

    Mit &other ( du nutzt den Adressoperator ), erhälst du die Adresse, auf welche sich die Referenz bezieht, damit also die Adresse des rechten Operanden.

    Du könntest auch

    if( *this != other )
    

    machen, jetzt vergleichst du die Objekte selbst, dazu müsstest du jedoch für deine Klasse Vector den != Operator überladen.

    Hoffe ich konnte dir helfen.

    Gruß freeG



  • ok danke euch!

    Ich hatte einfach falsche Vorstellung davon, was eine Referenz tut bzw. ist.
    Mit Referenz als Funktionsparameter wird vermieden, dass ein Objekt kopiert wird (Kopierkonstruktor). Der Funktion wird nicht die Kopie übergeben, sonder Objekt selbst. Deswegen braucht man & um die Adresse zu bekommen...

    ich hoffe mein Fazit ist korrekt 🙂

    gruß



  • Also dass die Funktion keine Kopie bekommt stimmt, sie bekommt nicht direkt das Original, sondern eben einen Aliasnamen, der sich auf das originale Objekt bezieht.
    Eine Referenz, braucht im Gegensatz zu einem Zeiger keinen Speicher, sie ist ja einfach nur ein Aliasname. Daher bezieht sich dann der Adressoperator auf den Aliasnamen, da dieser für das eigentliche Objekt steht, erhälst du die Adresse des eigentlichen Objektes.

    Also kurz gesagt, du hast es verstanden;-)

    Gruß freeG



  • fr33g schrieb:

    Eine Referenz, braucht im Gegensatz zu einem Zeiger keinen Speicher

    😕 Das stimmt ja wohl nicht, oder? 😮



  • CSpille schrieb:

    fr33g schrieb:

    Eine Referenz, braucht im Gegensatz zu einem Zeiger keinen Speicher

    😕 Das stimmt ja wohl nicht, oder? 😮

    Ja, das stimmt nicht. Letztendlich muss eine Referenz ja irgendwie im Maschinencode umgesetzt werden, und da kann es sein, dass sie irgendwo abgelegt werden muss. Es sei denn, der Compiler kann alle Zugriffe über die Referenz auflösen und sie eliminieren.



  • Mh ok sorry dann stimmte da meine Information nicht so ganz.
    Aber trotzdem bezieht sich der Adressoperator & auf das Objekt selbst.

    Mann kann aber nicht auf die Speicheradresse der Referenz selber zugreifen oder?

    Gruß freeG



  • fr33g schrieb:

    Mh ok sorry dann stimmte da meine Information nicht so ganz.
    Aber trotzdem bezieht sich der Adressoperator & auf das Objekt selbst.

    Mann kann aber nicht auf die Speicheradresse der Referenz selber zugreifen oder?

    Gruß freeG

    Zumindest nicht standardkonform...
    Es soll wohl mal nen Compiler-spezifischer Hack hier gepostet worden sein.



  • Dit_ schrieb:

    Referenz ist ja einfach die Speicheradresse, so wie Zeiger, nur dass man die Referenz nicht auf ein anderes Objekt "umlinken" kann. Richtig?

    Nein, nicht nur. Bei Weitem nicht.

    Nexus (von <a href= schrieb:

    hier)">Nun ja, es gibt schon ein paar nicht unbedeutende Unterschiede [zwischen Zeigern und Referenzen].

    • Zeiger sind Objekttypen, Referenzen nicht
    • Zeiger benötigen explizite Dereferenzierung
    • Zeiger können auf Null zeigen
    • Referenzen sind unveränderlich und müssen bei der Definition initialisiert werden
    • Zeiger erlauben Zeigerarithmetik

    Es ist also nur vernünftig, eine klare Grenze zu ziehen.

    CSpille schrieb:

    Es soll wohl mal nen Compiler-spezifischer Hack hier gepostet worden sein.

    Offiziell heisst das nein. Wir wollen ja keine Gerüchte verbreiten und Leute auf dumme Ideen bringen... 😉


Anmelden zum Antworten