Überschreibe beim Laden wohlmöglich den Stack. Nur wo?
-
SeppJ schrieb:
@schwudde: Da ist aber etwas falsch an deiner Erklärung über sizeof eines Strings. Mag sein, dass du das richtige meinst, aber sizeof(irgendwas) ist eine Compilezeitkonstante. Das Problem an deinem Beispiel ist, dass die Klasse kein POD-Typ ist und daher auch nicht wie einer behandelt werden darf.
Deine Meinung zu good() vs operator void* und operator! kann ich nicht nachvollziehen.
Ich habe das als Beispiel genommen weil ja nicht ersichtlich wie die Klasse "buildings" aufgebaut ist. Wenn er da z.B. std::string verwendet ist es ja ebenfalls kein POD-Typ.
"good()" weil damit auch das "eofbit" geprüft wird. Aber Du hast sicherlich recht, das "eofbit" wird man bei einem output stream sicher nicht gesetzt finden. Davon abgesehen hatte ich ja geschrieben das "ich" das so machen würde (wohl weil ich es eben aus gewohnheit so mache).
-
Das mit den 'In Klassen packen' hab ich schon öfters gehört. Nur ich verstehe das irgendwie nicht. Klassen sind doch nur gut, wenn ich verschiedene Instanzen eines Objektes anlegen will, oder? Und das soll in dem Spiel ja nicht der Fall sein.
Und dass meine Klasse nicht POD ist, weiß ich nicht. Mit Strings war sie nicht POD (was auch immer das heißen mag) und deswegen habe ich anstattdessen ein char array genommen... Die Werte Wood, Iron, Stone etc sind vom Typ float.Hier mal die .h der Klasse player:
#include <iostream> class player { private: int initNumber; int iStatusToPlayer; int iStatusToAi[12]; int prosperty; int forceStrength; int development; int timesTradedWithPlayer; int timesPlayerRejectedOffer; float aiWood, aiStone, aiIron, aiGold, aiFood, aiHumor; int aiDefend, aiAttack; int aiInhabitants; // True = Verbündet / False = / public: char *name; bool bStatusToPlayer; //Enemy or Friend? True = Feind False = Neutral bool bStatusToPlayerAlly; // Verbündeter? bool bStatusToAi[9]; // True = Neutral / False = Feind bool bStatusToAiAlly[9]; player(char* _name) : name(_name) { this->iStatusToPlayer = 0; this->prosperty = 0; this->forceStrength = 0; this->aiWood = 100; this->aiStone = 100; this->aiIron = 100; this->aiFood = 100; this->aiGold = 100; this->aiHumor = 1.0f; this->aiInhabitants = 100; this->development = 5.000f; this->timesTradedWithPlayer = 0; this->timesPlayerRejectedOffer = 0; this->aiAttack = 300; this->aiDefend = 300; for(int i = 0; i<9;i++) { this->bStatusToAi[i] = true; this->bStatusToAiAlly[i] = false; } this->bStatusToPlayer = false; this->bStatusToPlayerAlly = false; } void calculateDevelopment(); void calculateRessources(); void calculateStatusToAi(); void calculateStatusToPlayer(); void calculateForceStrengthAndHumor(); void calculateAll(); void checkEvents(); // Kontrolliert ob irgendwelche Werte besonders niedrig sind. Wenn ja, löst es Folgen aus void tradeWithPlayer(float &lWood, float &lStone, float &lFood, float &lIron, float &lGold, int luck); void setStatusToPlayer(int i); int getAttack(); int getDefend(); int getAiWood(); int getAiIron(); int getAiStone(); int getAiGold(); int getAiFood(); };
Zu den Stringstreams: Ich konvertiere beim schreiben doch die Zahlen in einen String, bzw sie können nur noch als string eingelesen werden. Und dann muss ich diese Zeilen doch über einen stringstream laufen lassen, oder? Anscheinend mache ich einen Gedankenfehler. Aber wo?
-
Die binäre Serialisierung deiner Player-Klasse scheitert an dem rohen char-Zeiger name. Da wird nämlich nur die Adresse gespeichert, nicht der Inhalt.
EiGelbb schrieb:
Zu den Stringstreams: Ich konvertiere beim schreiben doch die Zahlen in einen String
Und der operator>> konvertiert wieder zurück, genau das ist seine Aufgabe. Der Zwischenschritt über den Stringstream ist unnötig.
-
Ok, danke.
Und wie löse ich das Problemchen? Die Gegner sollten schon einen Namen haben. Und immer einer init-Number über switch(initnumber) aufzurufen wäre ein wenig Overkill, finde ich, oder?
Mit String geht es ja auch nicht. Deswegen dachte ich, machst du's mit Char... Aber wenn das auch nicht gehtBTW, kann mir jemand ein weiterführendes C++ Buch empfehlen, wo auch mal die Praxis ein wenig beleuchtet wird? Es ist ja schön und gut zu wissen, was Klassen so machen könnten, wie Templates funktionieren etc. Aber diese reinen Fälle kommen halt nie vor. Hatte bisher C++ für Spieleprogrammierer gelesen (80% des Textes besteht darin, dem Leser zu verdeutlichen, dass das eben gezeigte zu erklären den Rahmen des Buches sprengen würde), und C++ Objektorientiertes Programmieren von Anfang an, was mehr Nachschlagwerk als Lernbuch ist...
-
du brauchst keine char arrays benutzten. du musst dir halt die stream-operatoren überladen. ich glaube dazu gibt es auch artikel hier im forum.
und das mit dem konvertieren:
#include <iostream> int main() { double d; std::cin >> d; }
hier liest du auch ein double direkt ein
vario-500
Edit: für buchempfehlungen schau mal in signatur von Seppj
-
EiGelbb schrieb:
Hier mal die .h der Klasse player:
Kein POD.
Mit Strings war sie nicht POD (was auch immer das heißen mag) und deswegen habe ich anstattdessen ein char array genommen
Kaputtrepariert. Jetzt ist alles viel schlimmer, da du char-Arrays nicht verstanden hast.
POD (was auch immer das heißen mag)
Und was macht man, wenn man etwas nicht versteht?
Zu den Stringstreams: Ich konvertiere beim schreiben doch die Zahlen in einen String, bzw sie können nur noch als string eingelesen werden. Und dann muss ich diese Zeilen doch über einen stringstream laufen lassen, oder? Anscheinend mache ich einen Gedankenfehler. Aber wo?
Ich habe die Fehler hervorgehoben.
BTW, kann mir jemand ein weiterführendes C++ Buch empfehlen, wo auch mal die Praxis ein wenig beleuchtet wird?
Siehe meine Signatur. Du brauchst aber kein weiterführendes Buch, dir fehlen sämtliche wichtigen Grundlagen.
-
Meine persönliche Buchempfehlung:
http://www.amazon.de/Intensivkurs-C-Andrew-Koenig/dp/3827370299
-
Nachdem ich ja selber in letzter zeit sehr viele Bücher durchgearbeitet hatte um mich mit C++ auseinander zu setzen kann ich bisher nur eines wirklich empfehlen, Englischkenntnisse vorausgesetzt.
Online lesbar hier ...
-
Und wie mache ich das mit dem Überladen der Streams?! Habt ihr vielleicht einen Link wo das erklärt ist? Ich versteh nicht wie man >> oder << überladen kann?! Und vorallem wie man das dann anwendet. Und das mit den stingstreams geht wie ich es mache auch nicht. wenn ich direkt von dem string in die Float bzw Int schreiben will, meckert der Compiler ;_(
-
Von String in einen Integer bzw Float kannst du mit atoi(string/char array) für Integer und atof(string/char array) lösen.
http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/
http://www.cplusplus.com/reference/clibrary/cstdlib/atof/und hier noch ne kleine URL zu Operatoren
http://www.gia.rwth-aachen.de/Lehre/Cpp/script/online/node141.html
-
Wenn du eine schnelle Hilfe brauchst, dann:
http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.8
-
EiGelbb schrieb:
Und wie mache ich das mit dem Überladen der Streams?! Habt ihr vielleicht einen Link wo das erklärt ist? Ich versteh nicht wie man >> oder << überladen kann?! Und vorallem wie man das dann anwendet.
http://www.c-plusplus.net/forum/232010
Und das mit den stingstreams geht wie ich es mache auch nicht. wenn ich direkt von dem string in die Float bzw Int schreiben will, meckert der Compiler ;_(
Was willst du auch mit dem String? Schreib doch einfach in den Stream, ganz ohne Zwischenschritte! Und lesen genau umgekehrt!
Videonauth schrieb:
Von String in einen Integer bzw Float kannst du mit atoi(string/char array) für Integer und atof(string/char array) lösen.
http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/
http://www.cplusplus.com/reference/clibrary/cstdlib/atof/Das halte ich für einen ganz schlechten Ratschlag. Zum einen braucht er hier gar nichts umzuwandeln. Zum anderen, falls er es doch mal brauchen sollte, ist die Methode die er jetzt hat schon ganz ok. Vielleicht mal als Funktion, anstatt 30x den gleichen Code wiederholen. Und als Template.
-
Das mit dem Überladen des << versteh ich zum Teufel komm raus nicht...
Was soll mir das bringen, wenn ich da &ostream operator<<(ostream &xy, yx); hab?
Wofür brauche ich da den Rückgabewert, was bewirkt dieses Überladen nun und wie schreibe ich dann?
Ich krieg gleich ein Herzkasper, da ich nirgendwo im Internet was finde, womit ich es finde. Immer steht nur: Überlade einfach und dann einfach ausgeben.Hilfee! Ich versteh das hinten und vorne nicht. :_(
-
EiGelbbb schrieb:
Das mit dem Überladen des << versteh ich zum Teufel komm raus nicht...
Was soll mir das bringen, wenn ich da &ostream operator<<(ostream &xy, yx); hab?
Wofür brauche ich da den Rückgabewert, was bewirkt dieses Überladen nun und wie schreibe ich dann?#include <iostream> #include <string> using namespace std; class Datum { int tag, monat, jahr; friend istream& operator>>(istream &in, Datum &datum) { char point; return in >> datum.tag >> point >> datum.monat >> point >> datum.jahr; } }; class Stueck_Obst { string sorte; Datum ablaufdatum; friend istream& operator>>(istream &in, Stueck_Obst &obst) { return in >> obst.sorte >> obst.ablaufdatum; } }; int main() { Stueck_Obst foo; // Datensätze von der Form // Orange 12.34.4567 // Banane 76.43.2135 // usw. // ***************************************** // Wie du einen Datensatz einlesen würdest: // Nein. Das kann ich einfach nicht vormachen. Versuchs mal selber. // ***************************************** // ***************************************** // Wie man viel einfacher einen Datensatz einlesen würde: cin >> foo; // ***************************************** }
Außerdem nochmal eine frühere Antwort:
SeppJ schrieb:
Siehe meine Signatur. Du brauchst aber kein weiterführendes Buch, dir fehlen sämtliche wichtigen Grundlagen.
Dein früheres Buch war wohl nicht so gut. Der Title kommt mir auch schon verdächtig vor.
-
Ich glaub, ich bin einfach zu dumm um C++ zu lernen... Seit zwei Stunden verusche ich das Überladen zu verstehen, und ihr seit so nett und versucht mir zu helfen, aber bei mir steht da oben immer noch dick 'Bahnhof'.
Frage 1: was bewirkt das
char point
da? Und wo ist das definiert? Wie weiß der Compiler jetzt, dass er bei cin >> keine tastatureingabe erwarten soll sondern aus einer Datei lesen soll? Das soll er da doch oder? Ich sehe nicht, so cin gesagt wird, dass er überladen handeln soll. Und wie das mit Outpur geht weiß ich auch immer noch nicht...
Wenn ich jetzt eine Klasse Player habe:
ostream& operator<<(std::ostream& os, const player xy) { os << xy.getAiFood(); return os; }
Das würde doch jetzt bewirken, dass ich in den ersten Paramter des Operators, also in ein ostream-Objekt den Wert von xy.getAiFood() schreiben würde. Doch wie rufe ich diese Funktion auf? Irgendwo muss ich doch die Paramter übergeben? Also
ostream abc("filename.dat"); <<(abc,xy);
oder wie? Das sieht mehr sehr falsch aus.
Logischer würde mirostream abc("filename.dat"); abc << xy;
erscheinen. Doch: Wo wird da dem << gesagt, dass er überladen ist?!
Und wie lade ich das jetzt wieder? Ich schreibe ja nicht nur einen sondern gleich mehrere in eine Datei. getline kann ich ja nicht sagen. Wer weiß, ob dass Alles in einer Zeile steht.Also, meine konkreten Fragen:
-Woher weiß cin >>, welchen ostream ich meine?! Da steht ja nichts von einem ostream, sondern nur, dass ein Objekt eingelesen werden soll.
-Wie funktioniert das speichern und lesen mehrerer Elemente.
-Was bewirkt das char point in deinem Beispiel?
-WIE FUNKTIONIERT DAS?!Mein Problem ist wohl, dass alle Bücher bisher immer nur die Oberflächen erklärt haben.
"Mit cin >> gibst du Daten ein"... Doch was der Operator >> nun wirklich könnte, was cin eigentlich bedeutet, etc wird nirgends erklärt
Oder vielleicht bin ich wirklich nur zu dumm um das Alles zu verstehen
-
EiGelbbb schrieb:
Mein Problem ist wohl, dass alle Bücher bisher immer nur die Oberflächen erklärt haben.
"Mit cin >> gibst du Daten ein"... Doch was der Operator >> nun wirklich könnte, was cin eigentlich bedeutet, etc wird nirgends erklärt
Oder vielleicht bin ich wirklich nur zu dumm um das Alles zu verstehen
Deine Bücher machen das vielleicht so. Die Erklärung die du hier als Beispiel gibst ist auch schlecht bis falsch. Du hast auch tatsächlich überhaupt nicht verstanden, was cin bedeutet. Aber das sind viel zu viele, viel zu lange Fragen und die werden auch noch Folgefragen nach sich ziehen. Das kann ich nicht alles beantworten. Daher: Lies ein gutes Grundlagenbuch! Nichts für Spieleprogrammierer, für Dummies, von A bis Z oder in 21 Tagen, sondern ein gutes Buch!
-
cin ist selbst ein Streamobjekt des Typs std::ostream.
-
314159265358979 schrieb:
cin ist selbst ein Streamobjekt des Typs std::ostream.
ne,
istream
-
Hm, ok... Habe jetzt mal etwas rumprobiert.
Müsste es dann so aussehen?
ostream& operator<<(ostream &Stream, player& B) { Stream << B.getAiGold() << B.getAiFood() << B.getAiIron() << B.getAiStone() << B.getAiWood() << B.getDevelopment() << B.getForceStrength() << B.getHumor() << B.getInhabitants() << B.getProsperty() << B.getTimesPlayerRejectedOffer() << B.getTimesTradedWithPlayer(); return Stream; } istream& operator>>(istream &Stream, player& B) { Stream >> B.aiGold >> B.aiFood >> B.aiIron >> B.aiStone >> B.aiWood >> B.development >> B.forceStrength >> B.aiHumor >> B.aiInhabitants >> B.prosperty >> B.timesPlayerRejectedOffer >> B.timesTradedWithPlayer; return Stream; }
?
-
TyRoXx schrieb:
314159265358979 schrieb:
cin ist selbst ein Streamobjekt des Typs std::ostream.
ne,
istream
Ahjo, genau.