Öffentliches RPG Projekt
-
Syntax_error schrieb:
Basisgegenstand() : Basisgegenstand("",0)Warum nicht den Konstruktor gleich so schreiben:
Basisgegenstand(std::string n = "", int w = 0);Warum einmal struct und dann class?
was ist wert? Rüstungswert? oder doch wie viel wert die Rüstung ist?gruß
syntaxStimmt an default Werte hatte ich nicht gedacht.
Wert sollte einfach der allgemeine Preis/Wert eines Gegenstandes sein.
struct habe ich genommen, weil da alles public ist. (Du hast natürlich Recht vorallem die Verwendung von beidem impliziert eigentlich, dass ein Unterschied besteht)Auf die Namensgebung sollte man sich natürlich vorher einigen.

EDIT:
class Basis_gegenstand { protected: std::string name; int wert; public: Basis_gegenstand (const std::string& name="",int wert=0):name(name),wert(wert){} virtual ~Basis_gegenstand(){} friend std::ostream& operator<<(std::ostream& os,const Basis_gegenstand& bg); }; std::ostream& operator<<(std::ostream& os,const Basis_gegenstand& bg) { os<< "Name: "<< bg.name << "\n"; return os<< "Gegenstandswert: " << bg.wert << "\n"; } enum class Ruestungsart {NonExistent, Helm, Brustpanzer, Beinschutz, Armband, Ring, Halskette, Schuh, Schild}; std::ostream& operator<<(std::ostream& os,Ruestungsart art) { using RA=Ruestungsart; switch (art) { case RA::NonExistent: os<<"Fehler. Uninitialisierte Ruestungsart in operator<<(Ruestungsart)"; break; case RA::Helm: os<<"Helm"; break; case RA::Brustpanzer: os<<"Brustpanzer"; break; case RA::Beinschutz: os<<"Beinschutz"; break; case RA::Armband: os<<"Armband"; break; case RA::Ring: os<<"Ring"; break; case RA::Halskette: os<<"Halskette"; break; case RA::Schuh: os<<"Schuh"; break; case RA::Schild: os<<"Schild"; break; default: break; } return os; } class Ruestungsteil : public Basis_gegenstand { Ruestungsart art; int verteidigung; public: Ruestungsteil (const std::string& name="", int wert=0, Ruestungsart art=Ruestungsart::NonExistent, int verteidigung=0 ) :Basis_gegenstand(name,wert), art(art), verteidigung(verteidigung) {} ~Ruestungsteil(){} friend std::ostream& operator<<(std::ostream& os,const Ruestungsteil& teil); }; std::ostream& operator<<(std::ostream& os,const Ruestungsteil& teil) { os<< static_cast<Basis_gegenstand> (teil); os<< "Ruestungsart: " << teil.art << "\n"; return os<< "Verteidigungswert: " << teil.verteidigung << "\n"; }Gibt es noch bessere Möglichkeiten den "Basisklassenteil" und strongly typed enums auszugeben? (Vielleicht eine std::map<enum,string> ?)
-
Wozu sollte man überhaupt eine "uninitialisierte" Rüstung erlauben? Ist doch totaler Quatsch. Keine default Werte, und auch kein non-existant. Und int für Preis/Rüstung macht immer noch keinen Sinn, nimm std::uint32_t/std::uint16_t aus <cstdint>.
-
Weil ich nicht ausschließen kann, dass wir das mal in eine STL Datenstruktur packen, die einen default Konstruktor braucht? Erlauben, dass sowas ausgegeben wird wollte ich nicht. Dass das eigentlich eher wenig Sinn macht, weiss ich auch..
EDIT:
enum class Trankart {Lebenspunkte, Mana}; template <Trankart art> struct Test{ }; template <Trankart art> std::ostream& operator<<(std::ostream& os,Test<art>) { return os<< art; }besser?
-
Ich würde hier eine SQLite Datenbank statt Textdateien nehmen, oder wenigstens XML.
-
Nymer schrieb:
Weil ich nicht ausschließen kann, dass wir das mal in eine STL Datenstruktur packen, die einen default Konstruktor braucht?
Und welche wäre das?
-
cooky451 schrieb:
Nymer schrieb:
Weil ich nicht ausschließen kann, dass wir das mal in eine STL Datenstruktur packen, die einen default Konstruktor braucht?
Und welche wäre das?
std::array z.B. soweit ich weiss.
-
Nymer schrieb:
std::array z.B. soweit ich weiss.
Genau, und in einem std::array kannst du eh sofort alle Elemente mit {} initialisieren. Aber abgesehen davon, macht ein std::array für dich kaum Sinn. Du willst die Rüstungen doch dynamisch zur Laufzeit erstellen, da nimmst du eher einen vector und push_back. Für solche Konstruktoren, die das Objekt in einer Art Zombiestatus lassen, braucht man meiner Meinung nach schon einen sehr guten Grund.
-
Namenloser324 schrieb:
Bist du (Objektorientierter-)Programmieranfänger oder nur C++-Anfänger? Falls ersteres erachte ich das nicht so wirklich als sinnvoll, da wäre es eher von nützen wenn es jemand machte, der schon recht versiert im Programmieren ist.
Behersche im gewissenmasse OOE
-
Hallo Zusammen ich mach mal schnell ein Update, was ich alles gemacht habe udn wieso:
Ich habe zuerst mal mit den Seperatisierungen der Klassen begonnen.
Folgende Klassenfiles habe ich erstellt:
Monster.h
class Monster { public: int MonsterLeben, MonsterMana, MonsterGeld, MonsterEXP, MonsterLevel, MonsterAngriff, MonsterVerteidigung, MonsterSchaden, MonsterRuestungsWert; std::string MonsterWaffeName, MonsterName; Monster() : MonsterName(""), MonsterWaffeName(""), MonsterLeben(0), MonsterMana(0), MonsterGeld(0), MonsterEXP(0), MonsterLevel(0), MonsterAngriff(0), MonsterVerteidigung(0), MonsterSchaden(0), MonsterRuestungsWert(0) { //Konstruktorrumpf } Monster( //Konstruktor mit Parametern std::string const & MonsterName, std::string const & MonsterWaffeName, int MonsterLeben, int MonsterMana, int MonsterGeld, int MonsterEXP, int MonsterLevel, int MonsterAngriff, int MonsterVerteidigung, int MonsterSchaden, int MonsterRuestungsWert) : MonsterName(MonsterName), //Zuweisung Parameter zur Membervariablen MonsterWaffeName(MonsterWaffeName), MonsterLeben(MonsterLeben), MonsterMana(MonsterMana), MonsterGeld(MonsterGeld), MonsterEXP(MonsterEXP), MonsterLevel(MonsterLevel), MonsterAngriff(MonsterAngriff), MonsterVerteidigung(MonsterVerteidigung), MonsterSchaden(MonsterSchaden), MonsterRuestungsWert(MonsterRuestungsWert) { } void MonsterKampf() { //Kampfhandlung } ~Monster() { //Destruktor } }; class Charakter : public Monster { public: int HelmWert, BrustWert, HandWert, ArmWert, HoseWert, GurtWert, SchuheWert, Schildwert; std::string HelmName, BrustName, HandName, ArmName, HoseName, GurtName, SchuheName, SchildName; Charakter() : HelmWert(0), BrustWert(0), HandWert(0), ArmWert(0), HoseWert(0), GurtWert(0), SchuheWert(0), Schildwert(0), HelmName(""), BrustName(""), HandName(""), ArmName(""), HoseName(""), GurtName(""), SchuheName(""), SchildName("") { //Konstruktorrumpf } Charakter( //Konstruktor mit Parametern std::string HelmName, std::string BrustName, std::string HandName, std::string ArmName, std::string HoseName, std::string GurtName, std::string SchuheName, std::string SchildName, int HelmWert, int BrustWert, int HandWert, int ArmWert, int HoseWert, int GurtWert, int SchuheWert, int Schildwert) : HelmName(HelmName), //Zuweisung Parameter zur Membervariablen BrustName(BrustName), HandName(HandName), ArmName(ArmName), HoseName(HoseName), GurtName(GurtName), SchuheName(SchuheName), SchildName(SchildName), HelmWert(HelmWert), BrustWert(BrustWert), HandWert(HandWert), HoseWert(HoseWert), GurtWert(GurtWert), SchuheWert(SchuheWert), Schildwert(Schildwert) { } ~Charakter() { // Destruktor } }; class Haendler : public Monster { //Inventar void Verkaufen() { //Gegenstände des Händlers anzeigen und verkaufen. } void Einkauf() { //Gegenstände des Charakters anzeigen und kaufen. } }; class NPC : public Monster { // Interaktionen void Unterhalten() { //Smalltalk. } }; class QuestNPC : public Monster { //Quest void QuestGeben() { //Quest anzeigen, annehmen. } void QuestAbschliessen() { //Quest abschliessen, Belohnung geben. } };Quest.h
#include "stdafx.h" class Quest { public: Quest(void); std::string QuestName, QuestBeschreibung, QuestZiel, QuestGeber, QuestAbgaber, QuestStatus; ~Quest(void); int QuestIDStatus, QuestID; //QuestIDStatus 1=Angenommen, 2=Annehmbar 3=Abgebrochen und wider Annehmbar 4=Abgeschlossen };Items.h
#pragma once #include "stdafx.h" class items { public: items(void); ~items(void); std::string ItemName; int ItemPreis; }; class waffe : public items { int WaffeAngriff, WaffeVerteidigung, WaffeSchaden; }; class Ruestungsteil : public items { int RuestungWert; }; class Trank : public items { int TrankTyp, TrankWert; };Was haltet ihr bis jetzt davon?
Wo muss was angepasst/verbessert werden?Gruss,
Dragon4411
-
Dragon4411 schrieb:
Behersche im gewissenmasse OOE
Nach dem bisherigen aber mit starken Schwächen. Kenntnisse magst du haben, aber dir fehlt eindeutig Erfahrung für komplexeres Design. Das Projekt mag dennoch lehrreich sein, wobei ich zwei Einschränkungen mache:
1. Ich befürchte mangelndes Durchhaltevermögen (die Tendenz ist bereits vorhanden, da du dich noch nicht einmal durch ein Grundlagenbuch wirklich durchgekämpft hast) - dies mag sich aber mit der Zeit bessern, aus meiner Erfahrung ist dies aber in mindestens 90% der Scheiterungsgrund für Anfangsprojekte (und die Abbruchquote von solchen Projekten ist verdammt hoch).
2. Ihr solltet zumindest einen, nennen wir es mal "Mentor" haben (jemand mit Erfahrung, der sich immer mal etwas Zeit für euch nimmt, und regelmäßig eine "Code Review" durchführt), gerade weil das Projekt nicht so simpel ist, wie du vielleicht im ersten Moment meinst.
-
Dragon4411 schrieb:
Hallo Zusammen ich mach mal schnell ein Update, was ich alles gemacht habe udn wieso:
Fragen:
- Du beachtest viele Anmerkungen nicht, die du bereits bekommen hat (u.a. Mischung Groß-/Kleinschreibung...).
- Ist ein Charakter wirklich ein Monster?
- Wenn eine Klasse bereits Monster heißt, warum die Member nochmals mit "Monster" beginnen.
- Grundsätzlich sollte man sehr vorsichtig sein, Member öffentlich zu machen.
- Implementierung gehört in die Sourcedateien.
- Ich würde niemals mehr als eine Variable je Zeile schreiben, alleine schon um ggf. den Datentyp zu ändern ohne die Reihenfolge zwangsweise zu ändern etc.
- Ich würde in der Regel eine Header-/Sourcedatei pro Klasse machen, und nicht mehrere Klassen zusammen in eine Datei einfügen.
- Basisklassen sollten entweder ein nicht-öffentlichen oder virtuellen Destruktor haben.
- "int QuestIDStatus" ist eindeutig ein Kandidat für ein enum
-
Naja, header-only dateien kann er schon machen, wenn er das will.
So schlimm ist das auch nicht.
-
naja aber das hat dann wenig mit OOP zu tun...
-
#error schrieb:
naja aber das hat dann wenig mit OOP zu tun...
Was haben header-only klassen mit OOP zu tun?
-
Scorcher24 schrieb:
#error schrieb:
naja aber das hat dann wenig mit OOP zu tun...
Was haben header-only klassen mit OOP zu tun?
Warum glaubst du das die Frage jetzt in diesem Zusammenhang war. Da kein Zitat eingefügt wurden ist, ist der Zusammenhang unklar.
-
Ich habe mal irgendwo gelesen, dass der Compiler besser optimieren kann wenn er den Quellcode in einem Stück bekommt, also so wie hier beschrieben keine Trennung von Prototypen und Implementierung stattfindet. Was haltet ihr davon?
-
Grasshopper schrieb:
Ich habe mal irgendwo gelesen, dass der Compiler besser optimieren kann wenn er den Quellcode in einem Stück bekommt, also so wie hier beschrieben keine Trennung von Prototypen und Implementierung stattfindet. Was haltet ihr davon?
Ich halte gar nichts davon, da man sich auch mehr Abhängigkeiten macht wenn die Implementierung im Header schreibt. Das mag in einigen Fällen unproblematisch sein, ich schreibe meinen Code aber nicht so, das ich nachdenken muss wann ich die Implementierung zu verschieben habe. Mir ist ein konsequenter Stil wesentlich lieber, da mir dabei auch wesentlich seltener Fehler unterlaufen.
Zudem gehöre ich zu den Anhängern der Ansicht, das Implementierungsdetails (sofern sie durch C++ nicht zwingend in den Header müssen) immer in den Source gehören. Vermeidet auch die Gefahr das man doch irgendwo gegen eine Implementierung statt gegen die Schnittstelle programmiert. Und ich lese von fremden Code in der Regel ausschließlich den Header, dieser stellt die Schnittstelle dar gegen die ich Programmieren muss.
-
Grasshopper schrieb:
Ich habe mal irgendwo gelesen, dass der Compiler besser optimieren kann wenn er den Quellcode in einem Stück bekommt, also so wie hier beschrieben keine Trennung von Prototypen und Implementierung stattfindet. Was haltet ihr davon?
Das kann gut sein. Es ist wohl auch so, dass man ein bisschen schneller fahren kann, wenn man sich ne illegale Nitro-Einspritzung in den Motor bauen lässt. Würdest du deshalb für viel Geld dein Auto umbauen und Bußgelder riskieren, damit du morgens ne halbe Minute schneller im Geschäft bist, während dein Hauptproblem eigentlich der Stau jeden Morgen ist?
Der Compiler kann ggf. schnelleren Code generieren, ja. Wenn das Design und die Algorithmen Grüßtze sind, bringt das trotzdem nicht viel. Oft kann man an anderer Stelle viel mehr Performance rausholen. Und vor allem wird es schnell zum Wartungshorror, wenn man den Code enbloc schreibt. Damit macht man es den Kollegen nur schwieriger, die wirklichen Performancebrecher zu beheben.
-
Fragen:
- Du beachtest viele Anmerkungen nicht, die du bereits bekommen hat (u.a. Mischung Groß-/Kleinschreibung...).
- Ist ein Charakter wirklich ein Monster?
- Wenn eine Klasse bereits Monster heißt, warum die Member nochmals mit "Monster" beginnen.Damti wenn ich später noch weitere Klassen machen die Variablen unterscheiden kann.
- Grundsätzlich sollte man sehr vorsichtig sein, Member öffentlich zu machen.
Dies ist mir bekannt jedoch wäre es mühsam hier alles abzutrennen, nicht?
- Implementierung gehört in die Sourcedateien.
Wird gemacht

- Ich würde niemals mehr als eine Variable je Zeile schreiben, alleine schon um ggf. den Datentyp zu ändern ohne die Reihenfolge zwangsweise zu ändern etc.
Wird ebenfals geändert.
- Ich würde in der Regel eine Header-/Sourcedatei pro Klasse machen, und nicht mehrere Klassen zusammen in eine Datei einfügen.
Sprich auch die anderen "Unterklassen"?
- Basisklassen sollten entweder ein nicht-öffentlichen oder virtuellen Destruktor haben.
Werde ich mri duchlesen, was die Vorteile sind und es heir auflisten damit es die anderen auch sehen.
- "int QuestIDStatus" ist eindeutig ein Kandidat für ein enum
Da Stimme ich zu (nach dem ich nun enum durchgelesen habe).
Gruss & Danke,
Dragon4411
-
Anonymous schrieb:
Ich habe mal irgendwo gelesen, dass der Compiler besser optimieren kann wenn er den Quellcode in einem Stück bekommt, also so wie hier beschrieben keine Trennung von Prototypen und Implementierung stattfindet. Was haltet ihr davon?
Ich halte davon nicht sonderlich viel, weil man dann nicht vernünftig debuggen kann.