3Fragen zum Programmaufbau (Die Bücher offen gelassen haben)



  • Hallo,

    also ich hätte 3Fragen, die in 3Bücher unterschiedlich beantwortet werden...

    1.) Sind Globale Variablen wirklich "böse"?
    z.B wenn ich ein Spiel programmiere ist ja ein bool isRunning global sinnvoll? Oder sollte ich eine Spielklasse programmieren in der isRunning ein Member ist? (Das eine Buch hat eine Game Klasse gemacht, das andere einfach nur einen Header mit Funktionen+namepspace "game")

    2.)Sind std::vectoren oder std::list´s schneller wenn ich sehr oft den Inhalt/Größe verändere?
    Rein logisch müssten ja eigentlich die List´s schneller sein, weil die bei einem push_back nie den gesamten Inhalt an eine andere Stelle kopieren müssen, sondern nur die Pointer oder?

    3.) Gibt es einen Containertyp in dem ich verschiedene Kinderklassen (Also Klasse die den selben "Vater" haben) speichern kann? Oder muss ich mir für jede "Unterklasse" einen eigenen Container machen?

    Hoffe ihr habt Antworten für mich. Links die meine Frage beantworten reichen natürlich 🤡

    mfg Alexander



  • Alex126 schrieb:

    1.) Sind Globale Variablen wirklich "böse"?

    Ja.

    Alex126 schrieb:

    z.B wenn ich ein Spiel programmiere ist ja ein bool isRunning global sinnvoll?

    Nein.

    Alex126 schrieb:

    Oder sollte ich eine Spielklasse programmieren in der isRunning ein Member ist?

    Jedenfalls sinnvoller als global, aber dass diese Variable überhaupt notwendig bzw. sinnvoll ist, möchte ich mal stark bezweifeln.

    Alex126 schrieb:

    (Das eine Buch hat eine Game Klasse gemacht, das andere einfach nur einen Header mit Funktionen+namepspace "game")

    Deswegen wird hier meistens von Spieleprogrammierungsbüchern zum lernen von C++ abgeraten.

    Alex126 schrieb:

    2.)Sind std::vectoren oder std::list´s schneller wenn ich sehr oft den Inhalt/Größe verändere?

    Man kann nicht sagen welcher Container "schneller" ist, wenn das so wäre, würde man nur einen nutzen. Gut, du hast die Einschränkung "Inhalt/Größe wird oft verändert". Das reicht aber nicht. Grunsätzlich kann man nur die Performance von Operationen auf einem Container vergleichen, z.B. ist beim Iterieren über alle Elemente der Vector schneller. (Klar, liegt alles hintereinander im Speicher.) Einfügen geht bei der Liste schneller, wobei der vector hier immer näher an die Liste kommt, je weiter hinten eingefügt wird. (.push_back ist sehr schnell bei vector, push_front sehr langsam.) Es gibt aber noch mehr Datenstrukturen wie z.B. deque etc. Als Faustregel ist eine Liste immer dann schneller, wenn man
    - Recht viele Elemente hat oder diese sehr groß sind
    - Oft relativ mittig im Container einfügen/löschen will, und dabei die Reihenfolge der Elemente nicht verändern darf
    Sämtliche Performanceeigenschaften ergeben sich aber offensichtlich, sobald man diese Datenstrukturen verstanden hat. In empfehle einfach mal std::vector, std::list und std::deque nachzuprogrammieren.

    Alex126 schrieb:

    3.) Gibt es einen Containertyp in dem ich verschiedene Kinderklassen (Also Klasse die den selben "Vater" haben) speichern kann? Oder muss ich mir für jede "Unterklasse" einen eigenen Container machen?

    Das hat mit dem Container nichts zu tun. Wenn du zwei Klassen A und B hast wobei B public von A erbt dann ist B* implizit zu A* konvertierbar. Ergo kannst du in einen vector<A*>, list<A*>, whatever<A*> auch B* stecken. Damit das sinnvoll ist sollten diese Klassen noch virtuelle Methoden anbieten. (Ich hoffe das wird erklärt in deinen Büchern? Ansonsten einfach mal googeln.)



  • Au ja, ein list vs vector Flame :xmas2:

    cooky451 schrieb:

    Als Faustregel ist eine Liste immer dann schneller, wenn man
    - Recht viele Elemente hat oder diese sehr groß sind
    - Oft relativ mittig im Container einfügen/löschen will, und dabei die Reihenfolge der Elemente nicht verändern darf

    Der erste Punkt ist falsch, der zweite ist mir noch nie untergekommen.
    Listen sind dann wichtig wenn:
    - Verschiedene Listen zusammengefügt werden sollen
    - Der Speicherort eines Elementes nicht verändert werden soll (Iteratoren immer gültig)



  • il reendeer schrieb:

    Der erste Punkt ist falsch

    Nö. Wenn man z.B. nur 4 - 12 kleine Elemente hat, sind die Kosten für's Verschieben beim Einfügen in der Mitte quasi zu vernachlässigen.

    il reendeer schrieb:

    der zweite ist mir noch nie untergekommen

    Dann hast du offenbar noch nie eine std::map gebraucht. 😉



  • Mit 1. Punkt meine ich den ersten Spiegelstrich, nicht den 1. Teilsatz im 2. Spiegelstrich. Damit werden deine Argumente hinfällig.



  • Nein. Ich habe auch explizit genau diese Eigenschaft geändert, und gezeigt dass der vector jetzt wieder eine Option ist.



  • So danke für eure Antworten,

    ja das spieleprogrammieren Buch war mein Drittes.

    std::deque und std::map muss ich mir mal anschauen.

    Das mit dem Pointern auf die "Vaterklasse" hab ich mir gestern am Abend schon angeschaut und versteh ich auch soweit ganz gut...

    mfg Alexander



  • Nein, globale Variablen sind nicht boese. Manchmal braucht man globalen State eben, und dann machts keinen Sinn, seine globalen Variablen in nem Singleton zu verstecken.

    Man sollte halt nur genau das global machen, was auch wirklich global sein muss. Z.B. ein Logger fuer die Anwendung.



  • Man sollte halt nur genau das global machen, was auch wirklich global sein muss. Z.B. ein Logger fuer die Anwendung.

    Richtig, Manche Entitäten haben von der Logik her nun mal eine eher globale Natur.

    Man kann globale Variablen auch dann vermeiden ... aber leidet an anderen Stellen dafuer. Parameterübergaben z.b. Deine "globalen" Parameter sind dann halt Zwangs-Parameter bei der Erzeugung, wenn am Object oder in den Hirarchie danach der globale Parameter gebraucht wird. Das kann, muss aber nich, genauso umständlich, verwirrend etc sein ...

    Ist also dann auch ne Abwägungs-Frage.

    std::vector:
    Die meisten "Lehrbücher" nehmen den zum Einstieg, weil er mit dem c-Array am verwandesten und am besten erklärbar ist.
    Die Folge: Von Neueinsteigern viel zu oft benutzt!

    Der vector hat arg Situationsbedingtes Verhalten was die Performance angeht ...
    Als Vorteil / EIgenschaft bringt er dabei nur folgendes mit:
    - Schneller Index zugriff
    - Elemente / Speicher reservierbar
    - Elemente liegen am Stueck im Speicher vor (C-Array kompatiblitaet).

    Dementsprechend definieren sich auch die Anwendungsgebiete:
    - Du musst Schnell per positionsangabe auf ein Element zugreifen koennen, ohne ne Iteration mit x Schritten anzufangen ...
    - Du willst speicher im voraus allocieren, so das einfuegeoperationen direkt kein allocator aufrufen
    - du brauchst ne structur um nen C-Interface zu bedienen ...

    Wenn von dem nix in Frage kommt, sind andere Container immer die bessere Wahl.

    Manchmal baut man sich auch benutzerdefinierte Container aus mehreren stl basiscontainern zusammen ....

    Oder muss ich mir für jede "Unterklasse" einen eigenen Container machen?

    In C++ kommts sehr auf die Anwendung drauf an ...
    Das DU mehrere Klassen in einen Container Sperren willst, deutet eigentlich schon an das Du sie "gleichbehandeln" willst -> Vererbung.
    Es sollte aber auch wirklich gemeinsame Funktionalitaet geben

    Vererbung hat aber auch Nachteile, grad in sachen Performance.
    Also versucht man das Gleichbehandeln durch generische Programmierung (Templates) aufzuloesen, dann kommst um unterschiedliche container nicht drumherum.

    Oft Abwägungssache !

    Ciao ....


Anmelden zum Antworten