Merkwürdiger Fehler, vielleicht liegts am Konstruktor?
-
Moin zusammen
Ich sitze zur Zeit an Konstruktoren, Vererbung und dem new/delete-Befehl. Ich hatte eigentlich gedacht, dass ich das nun recht gut verstehen würde, aber das war wohl eine Fehlinformation meinerseits.
Folgendes Problem:
Ich habe zwei Raumschiffe Schiff und Minenleger. Letzterer soll von ersterem Erben, aber beide sollen auch eigenständige Schiffe und somit "baubar" sein. Das lief bis zu dem Punkt auch ganz gut, bis ich eine zeigeDaten-Funktion eingebaut habe, die schlichterweise die einzelnen Daten zu den jeweiligen Schiffen ausgeben soll.
Im Hauptteil des Programmes soll gefragt werden, wie viele Schiffe und wie viele Minenleger gebaut werden sollen. Die entsprechende Menge soll per new-Befehl angelegt werden. In der for-Schleife soll nun jedes Schiff/jeder Minenleger durchlaufen werden. Bis auf die zeigeDaten-Funktion des letzten Schiffes/Minenlegers funktionieren die Sachen auch wirklich klasse.Hier mal der Code:
#include <iostream> using namespace std; class CRaumschiff { protected: int m_Farbe; int m_Energie; public: CRaumschiff () { m_Farbe =0; m_Energie = 1000; cout << "Raumschiff wurde erstellt!" << endl; } void Starten () {cout << "Startete!" << endl;} void Landen () {cout << "Landete!" << endl;} void zeigeDaten () { cout << "Farbe: " << m_Farbe << endl; cout << "Energie: " << m_Energie << endl; } }; class CMinenleger : public CRaumschiff { private: int m_Minen; public: CMinenleger () { m_Minen = 9; m_Farbe = 2; m_Energie = 600; } void lege_Mine () {cout << "Mine wurde gelegt! Es sind noch " << m_Minen << " Minen uebrig!" << endl;} void Starten () {cout << "Minenleger gestartet!" << endl;} void Landen () {cout << "Minenleger gelandet!" << endl;} }; int main () { CRaumschiff *Schiff = NULL; CMinenleger *Miner = NULL; int schiffmenge; int minermenge; cout << "Wie viele Schiffe soll ich bauen?" << endl; cin >> schiffmenge; Schiff = new CRaumschiff[schiffmenge]; for (int i=1; i <= schiffmenge; i++) { cout << "Schiff Nr. " << i << endl; Schiff[i].Starten (); Schiff[i].Landen(); Schiff[i].zeigeDaten(); cout << endl; } cout << "Wie viele Miner soll ich bauen?" << endl; cin >> minermenge; Miner = new CMinenleger [minermenge]; for (int i=1; i <= minermenge; i++) { cout << "Miner Nr. " << i << endl; Miner[i].Starten(); Miner[i].lege_Mine(); Miner[i].Landen(); Miner[i].zeigeDaten(); cout << endl; } delete [] Miner; delete [] Schiff; Miner = NULL; Schiff = NULL; return 0; }Egal, wie viele Schiffe oder Minenleger man bauen lässt, die Daten des jeweils letzten sehen aus, wie durch den Fleischwolf gedreht.
Beispiel:
Ich baue drei Schiffe.
Schiff 1 sieht gut aus. Schiff zwei sieht gut aus. Schiff drei hat auf ein Mal Farbe -33686019 und Energie 0.
Ich baue 4 Minenleger.
Bis auf das letzte: Alles klappt. Aber Minenleger vier schleudert mir folgendes entgegen:
Es sind noch 255107023 Minen übrig, Farbe -33686019, Energie: -572662307.
Das ließt sich, als wären alle Minen auf ein Mal in die Luft gegangen.Kann mir jemand von euch erklären, warum das Programm so spannende Werte liefert? (Und worin mein Fehler liegt, dass dieses Programm meint, soetwas tun zu müssen?)
Ich würde mich wirklich sehr über Antworten freuen

(Für diejenigen, denen Teile des Codes bekannt vorkommen: Ich arbeite mich durch "C++ für Spieleprogrammierer" durch)
-
Arrays in C++ sind nullbasiert! Dein erstes Schiff hat also den Index 0, dein drittes den Index 2.
Statt
for (int i=1; i <= schiffmenge; i++)probier mal so:
for (int i=0; i < schiffmenge; i++)Btw, std::vector würde dir die manuelle Speicherverwaltung abnehmen. Dann könntest du z.B. kein delete[] vergessen (std::vector räumt selber auf). Außerdem hättest du den Fehler vermutlich selbst gefunden (da hättest du dann eine Fehlermeldung bekommen, "vector subscript out of range" oder so). Schau dir die Klasse ruhig mal an. Ist wesentlich komfortabler als rohe Arrays.
-
1. Arrays gehen von 0 los. Du bist also immer eines daneben und der letzte ist daher irgendwas über den Grenzen der Arrays.
2. Wenn man new[] benutzt, ist das auf jeden Fall sehr suboptimal, denn es ist bloß std::vector ohne dessen Vorteile.edit: Zu langsam...
-
Dankeschön :D!
Jemine, sobald ich mich an etwas Neuem versuche, vergesse ich jedes Mal, dass Arrays auf 0 beginnen. An meinem "Hauptrechner" habe ich mir schon ein großes, gelbes Post-It deswegen geklebt...
Danke euch beiden, nun funktioniert es.std::vector klingt interessant, das werde ich mir ansehen. Danke für den Tipp

-
Nachdem das wichtigste gesagt wurde: Warum beginnt dein Klassenname mit C?
-
1. Weils eine Class ist und ich mir das irgendwie angewöhnt habe, da
2. Mein Buch sagt, ich soll das machen
(Und solange ich noch am Üben bin, halte ich mich gerne an Vorgaben. Das macht das Vergleichen von Code irgendwie einfacher)
-
314159265358979 schrieb:
Nachdem das wichtigste gesagt wurde: Warum beginnt dein Klassenname mit C?
Das ist immer noch Ansichts- bzw. Geschmackssache. Das VS unterstützt das sogar teilweise atkiv.
-
Welches Buch?
-
Siehe oben: "C++ für Spieleprogrammierer"
