Warum Polymorphismus nur bei Referenzen/Zeigern möglich?



  • Hallo,

    warum ist Polymorphismus nur bei Referenzen und Zeigern möglich?



  • http://en.wikipedia.org/wiki/Object_slicing

    Ist allerdings nur eine Faustregel, man kann Polymorphismus auch ohne Referenzen/Smartpointer machen.



  • Wenn das abgeleitete Objekt größer ist, kann es nicht in dem vom Compiler reservierten Speicher für das Basisklassenobjekt untergebracht werden -> Verweis nötig -> Referenz oder Zeiger



  • nix_ schrieb:

    Wenn das abgeleitete Objekt größer ist, kann es nicht in dem vom Compiler reservierten Speicher für das Basisklassenobjekt untergebracht werden

    Falsch, der Compiler macht das ohne zu meckern. Und das Problem tritt auch auf, wenn das abgeleitete Objekt gleich viel/weniger Speicher als die Basisklasse benötigt.



  • So ein Blödsinn.
    Das ist der Grund warum Polymorphie ohne Zeiger/Referenzen i.A. nicht möglich ist. Willst Du vielleicht einen Compiler der nur bei manchen Subklassentypen (die eben nicht größer sind als die Basisklasse) polymorphe Methodenaufrufe erlaubt? Nein, also ist es gerenell nicht möglich.



  • Die Frage ergibt für mich keinen Sinn. Ich würde gerne mal ein Programm sehen, das sich nicht so verhält wie erwartet, weil Polymorphismus angeblich nur mit Pointern/Referenzen funktioniert.

    edit: Zum Slicing:

    Derived d;
    Base b(d);  // Slicing
    

    b ist ein Objekt vom Typ Base, es wird über den Kopierkonstruktor von Base erzeugt. Mit der Größe der Objekte hat das überhaupt nichts zu tun.



  • @nix_: Also dürfte laut dir das nicht kompilieren?

    struct A {
      A(int a=0) : a(a) {}
      int a;
    };
    
    struct B : A {
      B() : A(1), b(1) {}
      int b;
    };
    
    void f(A a) { std::cout << a.a << '\n'; }
    
    int main()
    {
      B b;
      f(b);
    }
    


  • Bashar schrieb:

    Die Frage ergibt für mich keinen Sinn. Ich würde gerne mal ein Programm sehen, das sich nicht so verhält wie erwartet, weil Polymorphismus angeblich nur mit Pointern/Referenzen funktioniert.

    code

    was erwartet man?
    ok als erfahrener erwartet man genau die ausgabe

    aber als anfänger denkt man, es kommt immer B raus



  • Bashar schrieb:

    Die Frage ergibt für mich keinen Sinn. Ich würde gerne mal ein Programm sehen, das sich nicht so verhält wie erwartet, weil Polymorphismus angeblich nur mit Pointern/Referenzen funktioniert.

    Hier ein Beispiel für meine Frage. Warum ist es nicht möglich, polymorphes Verhalten an der Stelle (1) zu haben? Bei einer Referenz (2) sag ich ja auch, dass der statische Typ B& ist und trotzdem wird der dynamische Typ verwendet, nämlich der Typ, auf den die Referenz tatsächlich verweist.
    Warum ist das nicht auch an der Stelle (1) möglich? Weil dadurch immer der Copy CTOR/operator= aufgerufen wird, und somit der Typ bei einer Variable vom Typ B immer B ist und niemals D sein kann?

    struct B
    {
        virtual void print()
        {
            cout<<"Base"<<endl;
        }
    };
    
    struct D : public B
    {
        virtual void print()
        {
            cout<<"Derived"<<endl;
        }
    };
    
    int main()
    {
    
        B b;
        D d;
    
        // Variablen von Typ B (1)
        B vb=b;
        B vd=d;
    
        vb.print(); //-> Base
        vd.print(); //-> Base
    
        // Variablen vom Typ B& (2)
        B& rb=b;
        B& rd=d;
    
        rb.print(); //-> Base
        rd.print(); //-> Derived
    
        return 0;
    }
    


  • vbcvbc schrieb:

    Weil dadurch immer der Copy CTOR/operator= aufgerufen wird, und somit der Typ bei einer Variable vom Typ B immer B ist und niemals D sein kann?

    Ja.



  • Dass da der Kopierkonstruktor benutzt wird, ist eher eine Folge und nicht die Ursache. Es ist schlicht und einfach so, dass das ein Objekt vom Typ B ist und nichts, was aussieht wie B und unter der Haube was anderes.



  • vb ist eine Variable vom Typ B. Dass dieser über eine Instanz von einer abgeleiteten Klasse initialisiert wurde, ist da egal. Der Typ bleibt B.

    Eine Referenz oder ein Zeiger verweisen auf ein Objekt. Die Referenz oder der Zeiger weiß, dass das referenzierte Objekt vom Typ B ist. Und eine Instanz der abgeleiteten Klasse D ist ja auch vom Typ B, da es davon abgeleitet ist.



  • danke für die antworten!


Anmelden zum Antworten