Wann static Methoden verwenden?



  • Danke für die AW. Interessanter Lösungsvorschlag!

    Zu den Interfaces:
    Hab das Buch "Design Patterns: Elements of Reusable Object-Oriented Software" gelesen, und dort wurde auch bei C++ Code immer mit (expliziten) Interfaces gearbeitet.
    Ist in C++ aber trotzdem von (expliziten) Interfaces abzuraten?

    Zu std::vector und 2d Arrays:
    Das ganze würde ja zu vector< vector<int> > führen.
    Ist das performant? Wäre es evtl. besser, an der Stelle boost::multi_array zu verwenden?

    Zu den Zeigern:
    Die Instanz von CTicTacToe ist nicht Besitzer vom übergebenen IViewer Zeiger, daher wäre es an der Stelle fatal, diesen Zeiger am Ende der Lebensdauer zu löschen.
    Als Referenz kann ich den IViewer aber auch nicht übergeben/speichern, da auch ein 0 Zeiger möglich sein soll. Daher geht ein roher Zeiger an der Stelle schon ok.



  • Noch was zu den "monolithischen, mega-mässigen Gottes-Klassen":
    Kennst du ein gutes Buch bzw. eine Website, die das von dir vorgeschlagene Design (also kleine Klassen mit den Daten und nur den nötigsten Methoden, und freie Funktionen zur Manipulation dieser Klassen) in C++ gut erklärt?



  • Soviel gibt es da eigentlich nicht zu erklären.

    Soweit ich es verstehe, sind Klassen dafür da, zusammengehörige Daten und Funktionen vom Rest des Programm abzukapseln.

    Der Vorteil darin ist z.B. der, daß man den Programmcode in einzelne Module aufteilen kann. Diese sind übersichtlicher und leichter wartbar.



  • static_function_frage schrieb:

    Ist in C++ aber trotzdem von (expliziten) Interfaces abzuraten?

    Keine Ahnung, was ein "explizites" Interface sein soll, aber wenn du ein Interface brauchst, kannst du natürlich eines verwenden.



  • Wäre es evtl. besser, an der Stelle boost::multi_array zu verwenden?

    Ja.
    Ich zitiere mal:

    <a href= schrieb:

    Boost.Multiarray Doc">Boost MultiArray is a more efficient and convenient way to express N-dimensional arrays than existing alternatives (especially the std::vector<std::vector<...>> formulation of N-dimensional arrays).



  • Danke fürs Feedback!


  • Mod

    Also meiner Erfahrung nach ist (bzw. war vor ein paar Jahren) boost::multi_array unbrauchbar langsam. Für ein einfaches 2D-Array nimm einen Wrapper um einen 1D-vector, der die Indizes passend umbricht.



  • Ich finde die Philosophie sich boost reinzuholen für ein bisschen TicTacToe echt für Übertrieben.

    Was "static" angeht gibt es meiner Meinung keinen Grund die Routine nicht einfach in einen entsprechenden Namespace zu packen. Ich denke Pattern profitieren besser von static, indem man z.B. sowas wie Singleton implementiert.

    Alleine schon der Gedanke: ich implementiere eine static Funktion, der ich etwas über die Klasse übergebe, und ein Ergebnis bekomme, könnte man genauso ohne Parameter als echte Methode implementieren. Hingegen der Singleton wird ja vor der Existenz eines Objekts aufgerufen und erzeugt dieses.

    Oftmals wird allerdings vermittelt, dass die ganzen Methoden mit instantiiert werden und static Funktionen nur einmal existieren: Blödsinn! Mit anderen Worten man kommt ohne aus.
    Es gibt eine Hand voll Frameworks, die streng hierarchisch arbeiten und jede Klasse eine gleichnamige static Funktion implementieren muss, damit die Hierarchie funktioniert.



  • Ich finde die Philosophie[,] sich boost [für ein bisschen TicTacToe] reinzuholen[,] echt für [ü]bertrieben.

    Es geht nicht darum, für welche Größenordnungen von Projekten man Boost einbeziehen sollte.
    Boost ist - mittlerweile - zu einer Ergänzung der Standardbibliothek geworden, und wird mittlerweile auch so konsistent genutzt wie diese; es ist fast gar nicht mehr wegzudenken.
    (Vgl. mit welcher Nebenläufigkeit Boost ins Spiel kam)

    Daher sollte es für den C++-Programmierer mMn keinen bemerkenswerten Aufwand darstellen, Boost in seine Projekte einzubinden.

    Folglich kann es nicht für übertrieben gehalten werden, genau das zu tun.



  • PhilippHToner schrieb:

    Alleine schon der Gedanke: ich implementiere eine static Funktion, der ich etwas über die Klasse übergebe, und ein Ergebnis bekomme, könnte man genauso ohne Parameter als echte Methode implementieren. Hingegen der Singleton wird ja vor der Existenz eines Objekts aufgerufen und erzeugt dieses.

    Im Falle von FindWinner übergebe ich zwar auch die Membervar m_PlayGround[][]. Allerdings verwende ich diese Funktion auch für die KI, um Spielzüge und damit eben auch andere Spielfelder zu bewerten. Daher als Parameter das Spielfeld.

    Für ein einfaches 2D-Array nimm einen Wrapper um einen 1D-vector, der die Indizes passend umbricht.

    Es handelt sich ja um eine Feld mit statischer Größe Weite x Höhe, in dem Fall eben 3x3.
    Warum soll ich da überhaupt einen vector verwenden, der ja dynamisch Speicher anfordert?
    Ein Wrapper um ein 2d Array, welchem ich mit Template Parametern die Größe sowie den Typ zuweise sollte doch reichen.



  • Viel schlimmer ist doch den Namen der Klassen mit "C" zu beginnen.



  • multi_array und PlayGroundSize für ein Tic-Tac-Toe sind IMHO so sinnvoll wie
    const unsigned int days_in_week=7; für einen Kalender...



  • Muss man Tic-Tac-Toe auf 3x3 spielen?
    Muss eine Marswoche auch 7 Tage haben?



  • Swordfish schrieb:

    Muss man Tic-Tac-Toe auf 3x3 spielen?
    Muss eine Marswoche auch 7 Tage haben?

    Ein Tic-Tac-Toe hat 9 Felder. Es kann aber sicherlich auch im 8 dimensionalen gespielt werden mit einer dementsprechenden Anzahl von Feldern...
    Bei der "Woche" auf dem Mars: klär mich auf...
    Ich jedenfalls bin nicht der Meinung alles parametrisierbar machen zu müssen - Z.B. ein klassischen Tic-Tac-Toe und ein Wochenplaner für Erdzeit...


  • Mod

    Swordfish schrieb:

    Muss man Tic-Tac-Toe auf 3x3 spielen?
    Muss eine Marswoche auch 7 Tage haben?

    Bist du auch so einer der

    const int Eins = 1;
    

    macht, für den Fall, dass 1 mal seinen Wert ändern könnte? Man muss nicht immer alles bis zum letzten abstrahieren.

    Hier würde ich weder Vectorwrapper noch multiarray und erst recht nicht vector<vector> benutzen. Das sind 9 ints oder vergleichbare Datentypen! Also eine kleine(!) Compilezeitkonstante. std::array<Feldtyp, 9> oder (je nachdem, wie man es ansprechen möchte) array<array<Feldtyp, 3>, 3> würde ich als unterliegende Datentstruktur benutzen.





  • Swordfish schrieb:

    Im Kumbha stehst an: http://de.wikipedia.org/wiki/Darischer_Kalender#Aufbau_des_Kalenders 😉

    Dammit!
    Eigentlich spiele ich jeden Samstagabend Quantum Tic-Tac-Toe mit den Kumpels... 🙂



  • SeppJ schrieb:

    Bist du auch so einer [...]

    Manchmal. 😉



  • Tatsächlich habe ich nur gesagt, multi_array wäre besser als vector< vector<> > . Denn mit Multiarray kann man (neben den im Doc. genannten Vorteilen) bspw. wenigstens noch slicen und damit leichter das Feld nach Sequenzen abprüfen. 🤡

    Trotzdem ist natürlich std::array viel passender. Ich würde dann schon verschachteln, ist schließlich nur eine 3x3-Matrix.



  • Sone schrieb:

    Tatsächlich habe ich nur gesagt, multi_array wäre besser als vector< vector<> > . Denn mit Multiarray kann man wenigstens noch slicen und damit leichter das Feld nach Sequenzen abprüfen.

    Trotzdem ist natürlich std::array viel passender. Ich würde dann schon verschachteln, ist schließlich nur eine 3x3-Matrix.

    Wenn alle Anfänger (includes Sone) verwirrt sind, behaupten wir am Ende das Gegenteil.


Anmelden zum Antworten