Vererbung



  • Hi folgende Vererbung ist mir nicht ganz klar ich hoffe mir kann da jemand weiterhelfen....

    #include <iostream>
    using namespace std;
    
    class A {
    
    public:
    
    A(int j): i(j) {}
    
    A& operator=(const A& a) {
    cout << " A::operator=\n";
    i = a.i;
    return *this;
    }
    
    virtual void print(){ 
    cout << " A: i = " << i; 
    }
    
    private:
    
    int i;
    };
    
    class B : public A {
    
    public:
    
    B(int k): A(k),j(k*k) {}
    
    void print() {
    A::print();
    cout << "; B: j = " << j;
    }
    
    private:
    
    int j;
    
    };
    
    int main() {
    
    B b1(2), b2(3);
    cout << "b1: "; b1.print(); cout << endl;
    cout << "b2: "; b2.print(); cout << endl;
    cout << "b1 = b2:"; b1=b2; 
    cout << "b1: "; b1.print(); cout << endl;
    return 0;
    }
    
    // Ausgabe:
    // b1: A: i = 2; B: j = 4
    // b2: A: i = 3; B: j = 9
    // b1 = b2: A::operator=
    // b1: A: i = 3; B: j = 9
    

    bei der Ausgabe sind mir die ersten 3 Zeilen klar, in der 4ten Allerdings wundere ich mich warum j nicht 4 ist da ja der zuweisungsoperator nur in A ( also der Oberklasse ) beschrieben ist und hierbei nur i entsprechend übernommen wird. Was mich zu der idee führte das nach der zuweisung mit = und arbarbeiten des operators aus A nochmal der Kopierkonstruktor aufgerufen wird, allerdings entfernt man in A i = a.i; so ergibt sich i = 2 und j = 9

    kann mir jemand erklären warum ?


  • Mod

    Wenn du keinen eigenen Zuweisungsoperator deklarierst, macht der Compiler das für dich. Der vom Compiler generierte Zuweisungsoperator ruft in der üblichen Reihenfolge die Zuweisungsoperatoren aller Basisklassen und Member auf (kleine Bemerkung am Rande: das bedeutet, dass dieser Operator im Allgemeinen nicht exception-sicher ist). Genau das passiert hier für die Klasse B.



  • Erstmal danke für die Antwort,
    also wird für i der zuweisungsoperator aus A genutzt und für j vom compiler ein eigener erstellt ? Und warum falls das so ist wie ich grade schrieb wird dann sofern ich aus A i = a.i; rausnehme nicht auch automatisch einer für i geschrieben ( genau wie bei j ) ?


  • Mod

    Für i und j werden keine Zuweisungsoperatoren geschrieben. Beides sind ints, und der Compiler weiß bereits, wie man ints kopiert. Zuweiungsoperatoren können nur für Klassen überladen werden, und in jeder Klasse existiert wenigstens ein für diese Klasse überladener Zuweisungsoperator, weil das der Compiler für dich übernimmt, falls du es selbst nicht tust. Dieser vom Compiler generierte Zuweisungsoperator hat stets ein ganz bestimmtes Verhalten, indem alle Basisklassen und Member einzeln zugewiesen werden (was im Falle von Basisklassen oder Membern, die selbst Klassenobjekte sind, den Aufruf der jeweiligen Zuweisungsoperatoren zur Folge hat).
    Im Übrigen verhält sich das ganz analog zum Copy-ctor.



  • was aber nicht erklärt warum wenn in A i = a.i; gestrichen wird nur j übernommen wird, oder verhält es sich so das zu jedem nicht definierten vom compiler etwas erzeugt wird, da es für die Klasse A ja den = operator gibt wird dieser genommen und nur die elemente aus B mit dem vom Compiler erzeugtem = verarbeitet ?



  • Genau, wenn kein Zuweisungsoperator für eine Klasse existiert wird er vom Compiler (so wie er es meint) erstellt.
    Also wird bei einem leeren operator= einfach nichts kopiert.


Anmelden zum Antworten