[Anfänger] Funktionen dynamisch aufrufen?



  • Object Orientierung ist kein Muss. Die Map-Variante ist auch eine gute Möglichkeit! Es führen viele Wege nach Rom.



  • @Artchi: Könnte man nicht, um "etwas OOP" zu bewahren (xD) die Funktionale per std::bind an ein Objekt binden? Aber das wäre eh wieder nur irgendein Gefrickel 🙄



  • Natürlich bringt Objektorientierung nicht immer was. Aber das hier ist eigentlich ein ziemlich typischer Fall, bei dem OOP angebracht ist. Wie schon gesagt kannst Du eine Basisklasse Monster machen, da die Methode Taktik aufrufen und in den Unterklassen kannst Du dann definieren, was Taktik eigentlich ist. Da brauchst Du keinen inperformanten Vergleich über den Namen mehr, das wird alles intern automatisch gemacht.

    Stichwort wurde auch schon genannt: Polymorphie.

    Und je nachdem, wie aufwendig diese Taktik ist, bietet es sich dann auch, die Taktiken in eigene Klassen auszulagern, um sie für unterschiedliche Gegner wiederzuverwenden usw. usf. Das bietet später einen hohen Grad von Wiederverwendbarkeit an und ist, wenn man den Durchblick hat, auch sehr gut wartbar. Dafür wurde OOP gemacht.



  • Was genau ist an der Map-Variante nicht objektorientiert?



  • naja man bindet eine globale funktion an ein beliebiges string objekt. ok, map ist OOP und string auch aber der ansatz schreit ja schon nach polymorphie...



  • Skym0sh0 schrieb:

    naja man bindet eine globale funktion an ein beliebiges string objekt. ok, map ist OOP und string auch aber der ansatz schreit ja schon nach polymorphie...

    Genau das wird mit der map emuliert. nur weil kein "vitual" drin vor kommt, heisst es nicht, dass es etwas anderes ist.

    Ohh ich sehe, jetzt gleich beginnt wieder die Diskussion was OOP ist :).

    Nebenbei würde ich weder string noch map pauschal unter OOP einordnen. OOP ist nicht einfach nur "Funktionen und Daten zusammenklatschen".



  • Die Taktik-Methode wird wohl kaum das einzige sein, das sich von Gegner zu Gegner unterscheidet.
    Neben unterschiedlichen Grundeigenschaften (etwa Lebenspunkte), reagieren manche Gegner vielleicht auf Angriffe anders, bzw. können diese unter speziellen Bedingungen abwehren bzw. zeigen spezielles Verhalten bei anderen Ereignissen in der Spielwelt, was sich alles bequem mit virtuellen Methoden regeln lässt.
    Mit Klassen hat man sämtlichen gegnerspezifischen Code an einer Stelle im Code beisammen und nicht nach C-Manier an hundert verschiedenen Stellen im Projekt verteilt.



  • Aber auch der Entwurf mit virtuellen Methoden hat viele Nachteile. Natürlich kannst du Klassen "Oger" und "Magier" haben. Aber was ist mit Oger-Magiern? verhält sich im Nahkampf wie ein Oger, im Fernkampf wie ein Magier. In deinem Ansatz brauchst du ne dritte Klasse. Aber wenn du genug Kombinationsmöglichkeiten hast, dann verhält sich die Klassenanzahl exponentiell zu der Anzahl der Wahlmöglichkeiten. Und das ist tendentiell unschön. Niemand will so viele Klassen schreiben und dabei Code copy-pasten. Und wenn sich in einer implementation was ändert, musst du es direkt überall ändern.

    Die map-variante outperformed virtual da unglaublich, weil du einfach nur für jede Wahlmöglichkeit einen String speichern kannst.



  • otze schrieb:

    Aber auch der Entwurf mit virtuellen Methoden hat viele Nachteile. Natürlich kannst du Klassen "Oger" und "Magier" haben. Aber was ist mit Oger-Magiern? verhält sich im Nahkampf wie ein Oger, im Fernkampf wie ein Magier. In deinem Ansatz brauchst du ne dritte Klasse. Aber wenn du genug Kombinationsmöglichkeiten hast, dann verhält sich die Klassenanzahl exponentiell zu der Anzahl der Wahlmöglichkeiten. Und das ist tendentiell unschön. Niemand will so viele Klassen schreiben und dabei Code copy-pasten. Und wenn sich in einer implementation was ändert, musst du es direkt überall ändern.

    Die map-variante outperformed virtual da unglaublich, weil du einfach nur für jede Wahlmöglichkeit einen String speichern kannst.

    Falsch.



  • volkard schrieb:

    Falsch.

    richtig.

    Langsam wirst du unerträglich.



  • Wenn Du Die String-Sache weiter ausprogrammierst, wirst Du bemerken, daß Du doch nur auf Nahkampf und Fernkampf switchst, dann kaufst Du Dir Mar++us' Buch und stellst fest, daß Du virtuelle Funktionen hättest nehmen sollen.
    Und ich erwarte, daß ich das nicht mehr aussprechen muß; du hast die Anfangsgründe doch eigentlich schon hinter Dir.



  • volkard schrieb:

    Wenn Du Die String-Sache weiter ausprogrammierst, wirst Du bemerken, daß Du doch nur auf Nahkampf und Fernkampf switchst

    ich vermute mal, dass die Taktiken eines Magiers im Fernkampf anders sein sollten als die Taktiken eines Bogenschützen. Ich könnte ja auch einen Oger-Bogenschützen machen wollen 🤡.

    In der Tat hatte ich schon einmal das Problem der kombinatorischen Explosion. Ich habe einen anderen mechanismus zur Lösung verwendet, virtual kam am Ende aber trotzdem nicht mehr vor (und mir wurde es erspart, ca 125 Versionen einer Klasse zu schreiben).

    Worauf ich halt hinaus wollte: virtual ist nicht mehr die optimale Lösung, wenn deine Objektkategorien Strukturen haben, die die Menge der Kategorien groß werden lassen. In dem Fall: #Anzahl Rassen x #Anzahl Nahkampfstrategien x #AnzahlFernkampfstrategien. Da ist es besser nicht mehr zu sagen: "Ein Oger ist ein Gegner", sondern "Ein Gegner hat eine Rasse, eine Nahkampfstrategie und eine FernkampfStrategie". Die "hat"-Beziehung lässt sich recht unproblematisch auf unterschiedliche Arten Ausdrücken. Zugriff auf eine Map ist okay, Zeiger auch. Allerdings ist beim zeiger die map nur in einem anderen Teil des Programms versteckt.


Anmelden zum Antworten