Methodenzugriff



  • Hi,

    angenommen ich habe einen Pointer auf ein Objekt der Klasse A. Von A ist eine Klasse B abgeleitet, die eine Methode enthält, welche in A nicht existiert. Nun zeigt der Pointer (der eigentlich auf ein Objekt von A zeigen soll) auf ein Objekt von B (was ja Spezialisierung von A ist). Die Möglichkeit die mir einfällt ist ein Typecast. Ist das die eleganteste Lösung?

    Hier ein kleines Code-Beispiel:

    #include <iostream>
    
    class A {
        public:
            void foo() {
                std::cout << "A does foo\n";
            }
    };
    
    class B: public A {
        public:
            void bar() {
                std::cout << "B does bar\n";
            }
    };
    
    int main() {
        A* obj = new B();
        obj->foo();
        ((B*)obj)->bar(); // <-- um diese Stelle geht es
        return 0;
    }
    

    LG



  • Die eleganteste Lösung ist

    #include <iostream>
    
    class A {
        public:
            void foo() {
                std::cout << "A does foo\n";
            }
    };
    
    class B: public A {
        public:
            void bar() {
                std::cout << "B does bar\n";
            }
    };
    
    int main() {
        B obj;
        obj.bar();
        return 0;
    }
    

    😉

    So ein sog. Downcast (von Basisklassenzeiger nach Zeiger auf abgeleitete Klasse), ist praktisch immer ein Hinweis auf einen Designfehler. Denn überleg mal, was der Cast bedeutet; Wenn du an der entsprechenden Stelle im Programm nur einen Pointer auf ein A hast, dann aus dem Grund, dass der entsprechende Code mit jedem beliebigen A funktionieren soll. Wenn du dort nun deinen A* in einen B* casten müsstest, dann kann das eigentlich nur zwei Gründe haben: Entweder der entsprechende Code funktioniert eben doch nicht für jedes beliebige A und du solltest dort eigentlich von vorn herein statt einem A* einen B* haben, oder deine Abstraktion A modelliert überhaupt nicht, was du damit modellieren wolltest. Egal wie herum, in beiden Fällen zeigt sich durch den Cast ein Widerspruch in deinem Design, den es aufzulösen gilt...



  • Warum gehst du nicht den üblichen Weg über Polymorphie? Nenn die Methode in B auch foo und mach sie in A virtual - fertig...



  • kritzelklotz schrieb:

    Warum gehst du nicht den üblichen Weg über Polymorphie? Nenn die Methode in B auch foo und mach sie in A virtual - fertig...

    Ich will sie aber nicht überschreiben, sondern B soll A um eine weitere Methode erweitern.



  • Wenn schon casten, dann schau Dir mal z.B. dynamic_cast an.
    Gruß



  • Helmut.Jakoby schrieb:

    Wenn schon casten, dann schau Dir mal z.B. dynamic_cast an.
    Gruß

    👎
    👍 für dot



  • Was ist an 'Anschauen' so schlecht? Nicht wissen lassen und Dogma finde ich noch schlechter.



  • Was für ein Dogma meinst Du?

    In der Regel ist es so, dass man einen Downcast deswegen nicht braucht, weil an der Stelle, an der die abgeleitete Klasse gebraucht werden soll, diese auch bekannt sein soll. Oder, man interessiert sich nicht dafür, welcher Erbe direkt übergeben wird, will aber zulassen, dass es dort ganz unterschiedliche gibt und gerade dafür dient Polymorphie.

    Auf Polymorphie zu verzichten, aber den Downcast zu benutzen, bedeutet, dass man hier eigentlich auf eine Abstraktionsebene (nämlich Base*) gegangen ist, die man dann später doch nicht haben will (weil Downcast notwendig ist). Es gibt jetzt dafür einige Stellen, an denen das nun Mal so ist, beispielsweise auch in so gewissen UI-Situationen je nach Framework oder für manche Formen des Double Dispatching.

    Aber auf so eine allgemeine Frage wie hier, muss die Antwort lauten, dass man sich das Design noch einmal genau anschauen sollte, denn der Standardfall ist eben, dass ein notwendiger Downcast von schlechtem Design zeugt. Das ist einfach eine Erfahrungssache und Erfahrung hat dot einige. Es ist ein großer Vorteil darauf zurückgreifen zu können, denn später spart einem das evtl. viel Zeit, die man sonst durch Redesign oder durch langsameres (gemeint ist Entwicklerzeit) Erweitern/Ändern wegen nicht besonders schönem Design vergeudetet hätte. 🙂


Log in to reply