operator überladen, aber welchen?



  • Hi,

    jupp, hier sollte

    if( this != &a )
    

    stehen.

    Ich nutze keine Array's. Hier steht doch nur ein Zeiger auf ein double.

    Ja! Wenn ich

    MyClass a(2);
    MyClass b(12);
    
    ... 
    a=b;
    

    dann stimmt's *b.p hängt planlos in Raum (unerreicht)
    weil b.p zeigt auf die gleiche Speicherstelle wie a.p. Wobei in diesem Fall...upps

    nicht nur *b.p == *a.p sondern sogar b.p == a.p.

    Tjo, dass sollte der operator richten...

    Wenn ich aber die Objekte a und b über new erzeuge, dann funktioniert doch der
    Zuweisungsoperator nicht mehr. Wie kann ich denn dann a = b machen?



  • FrankTheFox schrieb:

    Ich nutze keine Array's. Hier steht doch nur ein Zeiger

    ähm... *ups*... ja, hast natürlich recht. Ist wohl doch noch zu früh 😉

    Es geht dir hier doch nur ums Prinzip, das ist kein "ernst gemeinter" Code?



  • Nö,

    nur ein Beispiel um zu sehen was ich machen muss wenn:

    A) Objektinstanz auf dem Heap
    😎 Objektinstanz statisch durch Variablen dekl. ( ohne new )

    für 😎 habe ich eine Lösung ( und ich denke auch verstanden 😃 )
    aber für A) nicht.



  • A) Smartpointer. Welcher genau, kommt auf deine Anforderung an (unique, Referenzzählung, ...)



  • Meinst Du jetzt die Zuweisung?

    Naja, bei b) weist Du ja objektA = objektB. Dasselbe musst Du bei a) auch machen. Und um aus einem Zeiger ein Objekt zu machen, gibt es den Stern-Operator. Sprich, (*zeigerA) ergibt objektA.

    Ergo: Du weist zwei Objekte immer einander gleich zu, durch a = b. Wenn a ein Zeiger ist, musst Du aus a ein Objekt machen (dereferenzieren).



  • Ok.

    also muss ich:

    MyClass* operator=( const MyClass* a)
    ...
    

    sowas machen? Oder bin jetzt komplett neben der Spur?



  • Nein, die Zuweisung geht immer gleich vonstatten, nämlich von Objekt zu Objekt. Es gibt nur den einen operator=(Objekt const& other) für die Kopie.

    Du musst nur beim Zuweisen darauf achten, zwei Objekte zu haben.

    Object a;
    Object b; // Objekte
    a = b; // Muster: OBJEKT = OBJEKT
    
    Object* a;
    Object* b; // Zeiger
               // Das Objekt, auf das a zeigt, ist "*a"
               // Das Objekt, auf das b zeigt, ist "*b"
    // Übung: Kombiniere das Muster OBJEKT = OBJEKT und das Wissen, wie man aus Zeigern Objekte macht
    


  • Was Du beobachtest ist, was schief gehen kann, wenn man die 3er-Regel nicht beachtet. Es fehlt Dir nicht nur ein Zuweisungsoperator sondern auch ein Kopierkonstruktor.

    FrankTheFox schrieb:

    MyClass& operator=( const MyClass& a)
    {
       if( this != &a )
       {
          delete p;
          p = new double;
          *p = *a.p;
       }
       return *this;
    }
    

    Das ist leider nicht Ausnahme-sicher. new kann in die Hose gehen, in welchem Fall die Funktion verlassen wird, ohne, dass *this in einem gültigen Zustand ist.

    FrankTheFox schrieb:

    Aber wenn ich

    MyClass* a = new MyClass(2);
      MyClass* b = new MyClass(12);
    
      a->print();
      b->print();
    
      b = a;
    

    ich bekomme

    *** glibc *** detected invalid pointer

    ich kann ja nicht den Operator von oben nehmen. Was muss ich überladen, damit die Zuweisung klappt?

    WTF?! Das sind normale, rohe Zeiger. Du kannst die Bedeutung des Zuweisungsoperators für rohe Zeiger nicht ändern. Die Zuweisung führt hier zu einem Speicherleck. Ich sehe nirgens ein delete, was zu der Fehlermeldung führen könnte.

    So macht man das:

    class indirect_int
    {
      // Invariante: ptr zeigt immer auf ein
      // gueltiges int-Objekt.
      int* ptr;
    
    public:
    
      indirect_int(int i=0)
      : ptr(new int(i))
      {}
    
      ~indirect_int()
      { delete ptr; }
    
      indirect_int(indirect_int const& x) // copy ctor
      : ptr(new int(*x.ptr))
      {}
    
      void swap(indirect_int & that)
      { std::swap(this->ptr,that.ptr); }
    
      indirect_int& operator=(indirect_int temp) // copy assign
      { this->swap(temp); return *this; } // per "copy & swap"-Trick
    
      int value() const
      { return *ptr; }
    
      void value(int newv)
      { *ptr = newv; }
    };
    
    inline void swap(indirect_int & a, indirect_int & b)
    { a.swap(b); }
    


  • LordJaxom schrieb:

    // Übung: Kombiniere das Muster OBJEKT = OBJEKT und das Wissen, wie man aus Zeigern Objekte macht
    

    Hi, wieder do. Also wenn ich dich richtig verstanden habe muss das dann so gehen.

    MyClass* a = new MyClass(2);
    MyClass* b = new MyClass(12);
    
    a->print();
    b->print();
    
    *b = *a;
    
    b->print();
    
    delete a;
    delete b;
    

    krümelkacker schrieb:

    WTF?! Das sind normale, rohe Zeiger. Du kannst die Bedeutung des Zuweisungsoperators für rohe Zeiger nicht ändern. Die Zuweisung führt hier zu einem Speicherleck. Ich sehe nirgens ein delete, was zu der Fehlermeldung führen könnte.

    Mein Fehler:
    wenn der Code (statische Objekterstellung) ausgeführt wird kommt ohne Zuweisungoperator wohl ein glibc aberr ich habe die glibc's durcheinander gebracht:

    *** glibc detected *** /home/blabla : double free or corruption (fasttop)...

    Tjo, stimmt der new kann in die Hose gehen.

    Gruß



  • --


Anmelden zum Antworten