Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!
Werbeanzeige
Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von »Techel« (28.04.2017, 19:53)
Dabei ist mir folgendes aufgefallen https://github.com/BlackScorp/DwarfForge…es/Rect.cpp#L37 ich habe hier die Eigenschaft "width" ich kann den Wert via this->width setzen und auch einfach with nutzen, Beides wird normal kompiliert ohne Probleme. Was ist "Best Pratice" ? Was sollte man nutzen? Was nicht?
Zitat
Außerdem habe ich in den C++ Tutorials was merkwürdiges gesehen, ständig wurden im Globalen Raum instanzen erstellt mit Pointern und irgendwo im Code wurde dann dieser Pointer angefasst. In PHP ist es zwar möglich, jedoch sollte man es vermeiden Globale Instanzen/Variablen etc zu nutzen, weil man nie direkt weiß welcher Teil des Codes die Variable verändert, debugging ist dann nicht mehr so schön. Sind die Tutorials einfach nur zu alt? Oder wurde es einfach nur aus Bequemlichkeit gemacht?
Zitat
Mein Spiel möchte ich später für mehrere Plattformen testweise kompilieren, ich nutze aktuell g++, ich hab mal versucht es mit gcc zu kompilieren, bekam aber eine menge an Fehlern und hab da auch nicht weiter recherschiert. Ist g++ eine Schlechte wahl um für andere Systeme das Programm zu kompilieren? Oder habe ich einfach zu viel komisches benutzt womit gcc nicht klar kommt? std::string zum Beispiel?
Ob du this->width oder width nutzt, ist dir überlassen, es ist das Gleiche, außer du hast eine lokale Variable mit demselben Namen, die den Member somit überdeckt. Ich lasse das this-> aus Übersichtsgründen weg.
Globale Variablen sind nahezu immer Mist, gewöhn' dir das also gar nicht erst an. Außnahmen können z.B. globale Logger-Objekte sein. Soll allerdings ein Objekt Zugriff auf ein anderes haben können, gib ihm einfach eine Referenz oder Zeiger darauf.
Wahrscheinlich hast du den Code mit dem C-Kompiler kompilieren lassen.
Es muss nur sichergestellt werden, dass diese 'Observer' vor dem Besitzer die Resource nicht mehr referenzieren. Es gibt also oft keinen Grund, std::shared_ptr zu benutzen.)
- Ziehe Zeigern Referenzen vor, denn Zeiger signalisieren, dass sie auch null sein können. Im Falle, dass du einen Nullzeiger nutzen möchtest, verwende nullptr statt dem hässlichen NULL.
Community-Fossil
Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer
NULL ist hässlich, weil es was Eigendefiniertes ist. C++ kennt 'nullptr' stattdessen. Dem "ziehe Pointer vor" muss ich widersprechen. Es gibt dafür eine einfache Daumenregel: Wenn das übergebene Objekt immer einen gültigen Wert haben muss, verlange eine Referenz. Wenn es aber optional ist und damit auch nullptr sein darf, muss es ein Pointer sein.
- Gewöhne Dir ein paar Konventionen an. Java-Style ist ok, also Klassen und Typen im CamelCase, Klammern auf der selben Zeile, Whitespace und sowas. Fang nicht mit ungarischer Notation an, auch wenn Dir speziell auf den Microsoft-Helferseiten gelegentlich noch sowas begegnet - Hungarian Notation ist sowas von 2002.
- Der Compiler macht eine Menge für Dich. Z.B. den Destruktor erzeugen, oder den Kopierkonstruktor, usw. Wenn Du wie in Rect.cpp den Destruktor nur leer implementierst, kannst Du ihn auch weglassen und damit den compilergenerierten benutzen. Wenn Du einen Kopierkonstruktor oder -operator implementierst, indem Du jedes Element per '=' zuweist, kannst Du den compilergenerierten nehmen. Der beste Code ist nicht geschriebener Code, weil er keinen Pflegeaufwand braucht.
- Ableitungen mögen gerade das Mittel Deiner Wahl sein, aber haben auch ihre Schattenseiten. Man kann in modernem C++ erstaunlich viel erschlagen, indem man ganz schlichte Nur-Daten-Strukturen baut. Ableitungen benutzt Du nur, wenn Du viele verschiedene Dinge hast, die alle an ein- und demselben Griff zappeln sollen.
- Wenn Du irgendwo im Code new oder gar new[] stehen hast, denk nochmal drüber nach. Normales new / delete ist mit unique_ptr und manchmal shared_ptr größtenteils ein Relikt der Vergangenheit. Und new[] ist einfach nur ein Bug. Es gibt quasi keinen Grund mehr, stattdessen nicht einfach einen vorallokierten std::vector zu nehmen und alle Vorteile davon (Leck-Sicherheit, Ausnahmensicherheit) geschenkt zu bekommen.
- Du kannst sehr viel Zeug lokal anlegen, anstatt es auf dem Heap anzulegen und einen Zeiger zu speichern. Ein Beispiel wäre z.B. der EntityManager in der MainScene. Anstatt eines Zeigers einfach direkt das Objekt als Member der Klasse MainScene anlegen. Jede new kostet Rechenzeit - Du kriegst immernoch mehrere Millionen davon pro Sekunde durch, aber es kostet doch deutlich mehr als Du vielleicht aus Garbage Collected-Sprachen gewohnt bist. Und es ist in modernem C++ erstaunlich oft überflüssig.
- Eine std::map<> allokiert für jeden einzelnen Eintrag. Also ein new / delete pro Eintrag. Aus dem Grund würde ich alle Entities erstmal nur in einen std::vector packen. Und erst, wenn Du das erste Mal tatsächlich eine Entity per StringId finden willst, legst Du eine std::map<> daneben, die die benamten Entities anhand ihrer ID speichert.
NULL ist hässlich, weil es was Eigendefiniertes ist. C++ kennt 'nullptr' stattdessen. Dem "ziehe Pointer vor" muss ich widersprechen. Es gibt dafür eine einfache Daumenregel: Wenn das übergebene Objekt immer einen gültigen Wert haben muss, verlange eine Referenz. Wenn es aber optional ist und damit auch nullptr sein darf, muss es ein Pointer sein.
Community-Fossil
Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer
Administrator
Werbeanzeige