Du bist nicht angemeldet.

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

1

31.08.2014, 18:17

Problem mit Klassen und Instanzen

Tach

Folgendes habe ich vor:

In dem kleinen Testspiel an dem ich arbeite soll es möglich sein am Ende jedes Durchlaufs die erreichten Punkte sowie einen dazu gehörenden Spielernamen zu speichern. Dazu habe ich mir eine einfache Klasse für den Spieler geschrieben in dem nur der Name und die Punkte gespeichert werden. Am Ende jedes Spiels (zumindest wenn der Spieler gewonnen hat und nicht die KI) wird nun also eine neue Instanz der Klasse mit den erreichten Punkten und Name erzeugt. So weit so gut.

Nun möchte ich aber die Liste aller gespeicherten Daten abrufen können. Den dazu nötigen Code habe ich auch so weit geschrieben, nur funktioniert es nicht so wie es sollte. Es werden zwar immer so viele Datensätze ausgegeben wie bisher gespeichert wurden, allerdings immer nur der als letztes gespeicherte korrekt. Alle anderen enthalten nur Datensalat.

Basiert habe ich das ganze auf dem Listing 7.9 auf Seite 205 des Buches "C++ für Spieleprogrammierer". Allerdings werden dort alle Instanzen in einem Rutsch erzeugt während bei mir einfach immer am Ende eines Spieldurchlaufs eine neue hinzu kommt (oder eben auch nicht). Ich dachte eigentlich ich wäre in der Lage das Beispiel entsprechend umzubauen so dass es so funktioniert wie ich will, aber offenbar habe ich mich da überschätzt ;)

Deshalb mal wieder die Frage an Euch, wo liegt der Fehler? Oder müsste ich sogar eine komplette andere Herangehensweise wählen?

Der Codeabschnitt in der main-Funktion der den Konstruktor aufruft und den Zähler für die Anzahl Datensätze erhöht:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    Cplayer *pplayer = NULL; // for saving player to highscore list
    int players = 0; // how many players in high score list?
    int score = 0;
    char chsave;

        if (score > 0)
        {
            cout << "Willst Du Deinen Erfolg fuer die Nachwelt festhalten? j/n" << endl;
            cin >> chsave;

            if (chsave == 'j')
            {
                players++;

                pplayer = new Cplayer(score);

                score = 0;
            }
        }


Der Codeabschnitt der die Highscore-Liste ausgeben sollte:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
        case 4:

            cout << ">>>HIGHSCORE<<<" << endl;
            cout << "---------------" << endl;

            for (int p = 0; p < players; p++)
            {
                pplayer[p].showdata();
            }

            break;


Die Klasse für die Datensätze mit den entsprechenden Funktionen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Cplayer 
{
public:

    // member variables
    //
    int m_score = 0;
    char m_name[21];

    Cplayer(int score) // constructor
    {
        m_score = score;

        cout << "Gib Deinen Namen ein (max. 20 Zeichen): ";
        cin.ignore();
        cin.get(m_name, 20);

        cout << "Spieler:   " << m_name << endl;
        cout << "Punkte:    " << m_score << endl;
    }

    void showdata() 
    {
        cout << "Spieler:   " << m_name << endl;
        cout << "Punkte:    " << m_score << endl;
    }

}; // class player


Vermutung:

Ich erzeuge so gar nicht mehrere Instanzen sondern überschreibe jedes mal wieder die Selbe.

Falls dem so ist, wie erzeuge ich mehrere Instanzen eine nach der anderen?

Falls nicht, wieso werden die Datensätze nicht korrekt ausgegeben?

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »theoneandonlyboiler« (31.08.2014, 18:23)


2

31.08.2014, 18:41

Du arbeitest mit Zeigern. D.h. du überschreibst jedes mal die Adresse für dein eigentliches Objekt, und kommst so nicht mehr an die vorherigen Objekte. Die rutschen nicht automatisch einfach eins weiter. Für das, was du möchtest, bietet sich ein std::list an, wahlweise auch std::vector.
Das sind Cotainer, in welche man Objekte einfügen und herauslöschen kann. Dabei benötigst du auch keine Zeiger, sondern kannst dir dein Objekt auf normale Art und Weise erzeugen.

C-/C++-Quelltext

1
2
3
4
5
std::list<Cplayer> playerList;
// ...
Cplayer newPlayer;
// setze die Werte von newPlayer
playerList.push_back(newPlayer);


.push_back fügt den neuen Player hinten in die liste an. Hier kann man auch .insert oder .push_front nutze. Google einfach mal nach "std::list" und du wirst genügend Dokumentationen zu dieser Klasse finden.

mfg

3

31.08.2014, 23:03

Ok, probier ich nächstes WE mal aus.

Vielen Dank :)

GMoney597

Frischling

Beiträge: 48

Wohnort: Roth

Beruf: Verwaltungsfachangesteller (Stadtverwaltung), Fitness-Trainer und Muay-Thai-Trainer

  • Private Nachricht senden

4

01.09.2014, 08:02

Hey OneAndOnly,

ich habe das gleiche Buch und ich habe dieses Beispiel nur grob überflogen, weil ich keine Zeiger mag
Später habe ich wie Antifreak schon erläutert hat, das ganze in einen Objekt-Vektor gepackt und BAMM - funktioniert
Ich mag auch keine Arrays für Namen :dead: :fie: -> lieber Strings (aber die kommen in dem Buch erst bei der STL,
soweit ich mich erinnere), diese müssen auch eingebunden werden

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
class Player
{
private:
string Name;
int Score;

public:
void NeuerScore();
void ShowScoreList();
}


So sähe meine Spielerklasse aus, weil auch in jedem Buch, das ich bisher gelesen habe, die Membervariablen privat zu halten sind.
In der Methode NeuerScore setzt du dann den neuen Spieler zusammen und schiebst ihn in deinen Vektor / deine List

5

01.09.2014, 11:59

Gibt es eigentlich auch eine Möglichkeit, String Felder im Nachhinein noch zu bearbeiten bzw umzubenennen.. Hatte gehofft dass es mal ein Java Update o.ä. in dieser Sache geben wird ..

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »ekonomie« (03.09.2014, 10:40)


6

01.09.2014, 12:25

Meinsts die Variablen umbenennen? Nein, das geht nicht.

GMoney597

Frischling

Beiträge: 48

Wohnort: Roth

Beruf: Verwaltungsfachangesteller (Stadtverwaltung), Fitness-Trainer und Muay-Thai-Trainer

  • Private Nachricht senden

7

01.09.2014, 12:32

Meinsts die Variablen umbenennen? Nein, das geht nicht.


kommt sowas denn zur Laufzeit vor????
Im Entwicklungsmodus ist das ja mit entsprechendem Aufwand machbar

8

01.09.2014, 13:06

Variablen und deren namen gibt es im fertigen programm nicht. Schau dir mal std::map an. Wofür brauchst du sowas?

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

9

02.09.2014, 14:35

Sollte er aber eher wissen wollen, ob man den Wert von Membern oder anderen Vairablen vom Typ String nachträglich verändern kann: ja, du solltest in der Lage dazu sein, andere Werte zuzuweisen.
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

10

03.09.2014, 10:39

Meinsts die Variablen umbenennen? Nein, das geht nicht.
okee... hatte dazu hier den Artikel gefunden: http://jaxenter.de/artikel/werte-von-fin…ickkiste-173984
da steht, dass werte von final feldern sich problemlos ändern lassen sollten .. oder fass ich das grad falsch auf??

Werbeanzeige