Polymorphie: Parameter und Zeiger



  • sollte im grunde kein problem sein. bei übergabe per value wir das objekt nicht plötzlich "beschnitten". du musst es in der methode nur wieder als B interpretieren lassen.

    so ist polymorphie allerdings eigentlich nicht gedacht. denn wenn deine methode ein objekt vom typ A erwartet (egal ob nu als pointer oder sonstwie), dann darf man als aufrufer erwarten, dass die methode ausschließlich methoden des typs A verwendet.

    deine methode würde ja auch "echte" typen A akzeptieren. und wenn du die nach B castest, fliegt dir das programm um die ohren.



  • Wenn du ein B als A übergibst passiert das gleiche wie wenn du eine Variable vom Typ A mit dem B konstruierst, also so:

    B b;
    A a(b); // ein neues A, initialisiert mit b
    

    Das nennt man "slicing", da b "auseinandergeschnitten" wird, und nur der "A Teil" von b nach a kopiert wird.

    Über a (also in deinem Fall dann das Parameter einer Funktion) kannst du natürlich nicht auf b zugreifen, da a (nachdem es einmal konstuiert wurde) nichtmehr wissen kann wie es ursprünglich initialisiert wurde. Und da a nur ein A ist und kein B hat es natürlich auch keine Membervariablen/-funktionen von B.



  • thordk schrieb:

    sollte im grunde kein problem sein. bei übergabe per value wir das objekt nicht plötzlich "beschnitten".

    Falsch. Per value heisst Kopie, und Kopie in dem Fall heisst slicing.
    Wer das A in der Funktion auf ein B& castet greift auf uninitialisierten Müll zu.



  • hustbaer schrieb:

    thordk schrieb:

    sollte im grunde kein problem sein. bei übergabe per value wir das objekt nicht plötzlich "beschnitten".

    Falsch. Per value heisst Kopie, und Kopie in dem Fall heisst slicing.
    Wer das A in der Funktion auf ein B& castet greift auf uninitialisierten Müll zu.

    da es um polymorphie geht, würde der OP in seiner funktion F ja auch hoffentlich dynamic_cast verwenden. und

    void F (A a)
    {
       dynamic_cast<B&>(a);
    }
    

    würde _immer_ eine ausnahme werfen. die gefahr, auf uninitialisierten müll zuzugreifen, sehe ich allerdings nicht sofort. was ich allerdings nochmal betonen möchte, ist das hier bei der übergabe per-value nicht einmal der A Teil von dem B Objekt, das übergeben werden soll betroffen ist- nur lokale kopien.



  • Ok, vielen Dank für die zahlreichen Antworten!
    Dass ich in jedem Fall nur auf eine Kopie des übergebenen Objektes zugreifen kann ist mir klar; ich war mir nur nicht sicher wegen des "slicing", denn in Java glaub ich würde das so nicht auftreten. Wie auch immer, danke für die Info, ist ein super Forum hier!



  • In Java kann man ja auch keine Objekte by-value übergeben ...



  • Und da es in Java AFAIK auch keine nicht virtuellen Methoden gibt tritt der Fall nichtmal dann auf wenn man eine "klassisch implementierte" clone() Methode verwendet... anders gesagt: solange man nicht explizit dafür sorgt dass es ein Problem gibt 🙂

    BTW: kann man in Java eigentlich das implizite "virtual" umgehen? Also das was man in C++ als "b->A::VirtFunc()" schreibt?



  • hustbaer schrieb:

    Und da es in Java AFAIK auch keine nicht virtuellen Methoden gibt tritt der Fall nichtmal dann auf wenn man eine "klassisch implementierte" clone() Methode verwendet... anders gesagt: solange man nicht explizit dafür sorgt dass es ein Problem gibt 🙂

    BTW: kann man in Java eigentlich das implizite "virtual" umgehen? Also das was man in C++ als "b->A::VirtFunc()" schreibt?

    Imho war da was mit super. (oder wars Super. ?)



  • geht mit super. super ist ne referenz auf die direkt übergeordnete klasse. ist aber nur innerhalb einer instanz verfügbar, nicht ins statischen methoden.

    java kann abstrakte methoden haben, allerdings dürfen die keinen body besitzen. sind also sozusagen immer pure virtual.



  • Ok, Danke.
    Kann man auch "super.super.super.foo()" schreiben? 😃

    EDIT: ich nehme an man kann dann von aussen aber nicht "Object neuesFoo = m_foo.super.clone();" oder sowas schreiben, oder?



  • über super hat man nur zugriff auf sichtbare felder und methoden des direkten vorgängers, staffeln lässt sich das nicht. gehört zum java klassenkonzept. und von aussen zugreifbar ist super auch nicht.


Anmelden zum Antworten