=-Operator



  • Ich raffs grad echt nicht! Folgendes:

    class Base 
    { 
    public:
     long xxx;
     Base()
     {
      xxx = 1;
     }
      virtual const Base& operator=(const Base& base)
      {
       xxx = base.xxx;
       return *this;
      } 
    };
    class Derived : public Base 
    { 
    public:
     long yyy;
     Derived()
     {
      yyy = 2;
     }
      virtual const Derived& operator=(const Derived& derived ) 
      { 
       yyy = derived.yyy;
        Base::operator=(derived); 
    
      return *this;
      } 
    };
    class Worker 
    { 
    public:
      Base* base1; 
      Base* base2; 
    
      long fkt() 
      { 
        base1 = new Derived(); 
        base2 = new Derived(); 
      ((Derived*)base2)->yyy = 3;
      printf("y1 %ld\n", ((Derived*)base1)->yyy);
        *base1 = *base2;
    
      printf("x1 %ld\n", ((Derived*)base1)->xxx);
      printf("x2 %ld\n", ((Derived*)base2)->xxx);
      printf("y1 %ld\n", ((Derived*)base1)->yyy);
      printf("y2 %ld\n", ((Derived*)base2)->yyy);
    
      return 1;
      } 
    };
    
    int main(int argc, char* argv[])
    {
     Worker w;
     w.fkt();
     return 0;
    }
    

    Ausgabe:
    y1 2
    x1 1
    x2 1
    y1 2
    y2 3

    Mit anderen Worten: Wieso wird der =-Op von Derived nicht aufgerufen?
    Das ich das mit ((Derived)base1) = ((Derived)base2) machen kann weiss ich auch, will ich aber nicht. Und das Membervariablen nicht xxx heissen und
    cout besser als printf ist, weiss ich auch. Ich denke das mein Problem
    aber auch so gut erkennbar ist.

    Danke im voraus!
    Jockel



  • Wieso wieso?????

    Das für den Compiler Base1 und Base2 nun mal die Klasse Base darstellt sagst du doch selber. Warum sollte er dann den = OP von derived aufrufen?



  • meinst du so:

    class Worker 
    { 
    public:
      Base* base1; 
      Base* base2; 
    
      long fkt() 
      { 
        base1 = new Derived(); 
        base2 = new Derived(); 
    	((Derived*)base2)->yyy = 3;
      printf("y1 %ld\n", ((Derived*)base1)->yyy);
        base2 = base1;
    
      printf("x1 %ld\n", ((Derived*)base1)->xxx);
      printf("x2 %ld\n", ((Derived*)base2)->xxx);
      printf("y1 %ld\n", ((Derived*)base1)->yyy);
      printf("y2 %ld\n", ((Derived*)base2)->yyy);
    
      return 1;
      } 
    };
    

    warum deklarierst du eigentlich den = op in der derived klasse virtuell?



  • @David_14
    nicht gut, dann verlierst du doch Base2 -> Speicherleck



  • rerr schrieb:

    Wieso wieso?????

    Das für den Compiler Base1 und Base2 nun mal die Klasse Base darstellt sagst du doch selber. Warum sollte er dann den = OP von derived aufrufen?

    Weil Base1 und Base1 nunmal Derived-Objekte sind. So dachte
    ich zumindest. Das Problem ist aber (wie ich jetzt weiss), dass der
    =-Op aus Derived den aus Base gar nicht überschreibt! Mmmmhh..
    wie macht man das denn dann?



  • Das kann so nicht funktionieren. In Base hast du die Funktion:

    virtual const Base& Base::operator=(const Base& base)
    

    und in Derived

    virtual const Derived& Derived::operator=(const Derived& derived)
    

    Das sind zwei verschiedene Funktionen, da sie verschiedene Parameter haben. Die zweite Funktion überlädt also nicht die erste.

    Um die erste zu überladen müsstest du eine solche Funktion schreiben:

    virtual const Base& Dervied::operator=(Base const & base)
    

    Diese müsste noch entscheiden, ob sich hinter der Referenz tatsächlich ein Base oder eine Derived Objekt befindet. Der virtuelle Dispatch findet nur beim Objekt statt, dessen Methode aufgerufen wird und nicht beim Argument.

    Das ganze macht man eigentlich nicht, sondern überlädt für alle Klassen

    virtual Base Base::clone()
    

    Dann kann man schreiben:

    *base1 = base2->clone();
    


  • Okay, danke, das hört sich vernünftig an.



  • @Ponto
    Bitte beachte den Unterschied zwischen "überladen" und "überschreiben". Ansonsten verwirrst du mehr als das du hilfst.



  • Hört sich doch nicht gut an:

    Ob ich jetzt den =-Op überschreibe oder eine Clone-Funktion ist
    doch völlig egal.

    *base1 = base2->clone();
    

    geht ja auch, wenn base1 vom Typ Derived1 und base2 Derived2 ist.
    Da definiere ich mir doch lieber den base& =-op in Derived und
    schau da nach, ob die Zuweisung okay ist.

    Trotzdem Danke an alle Beteiligten.

    Jockel


Anmelden zum Antworten