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

09.02.2014, 17:12

Daten vom HEAp abrufen.

Hallo

ich experimentiere derzeit mit der Möglichkeit Klassen auf den HEAP zu speichern. Also mit new und delete.

Das Funktioniert soweit auch ganz gut. So lange ich in einer Funktion bleibe heißt das. Hier der Code meiner experimente:

C-/C++-Quelltext

1
2
3
4
5
6
7
    CPlayer *pPlayer = NULL;

    // Spieler erstellen
    pPlayer = new CPlayer (Health, Level, MaxHealth, Starke, Geschiklichkeit, Stufe, Erfahrung, EXPLevelUp, Weapon);

    delete pPlayer;
    pPlayer = NULL;


Das funktioniert soweit ja auch. Nur nun meine Frage. Es nützt mir reichlich wenig, wenn ich nur innerhalb dieser Funktion mit den Werten arbeiten kann. Wie bekomme ich es hin, dass ich die Daten auch in anderen Funktionen oder sogar .cpp oder.hpp Dateien auslesen kann?

Habe da schon bei google gesucht aber irgendwie nichts gefunden.

Vielleicht habe ich das auch falsch verstanden und die Sache mit dem HEAP funktioniert nicht und ich muss es anders angehen?

Prinzipiell habe ich derzeit mehrere .cpp und .hpp Dateien. Daher auch die Fragestellung. Ich möchte das ganze ja auch ordentlich hinbekommen und nicht alles in die main() pfeffern.

Danke schon einmal. Gruß

Rok

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »R0kn1x« (09.02.2014, 17:18)


Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

2

09.02.2014, 17:21

Bei einer Funktion kannst du für einen Parameter auch CPlayer* als Datentyp des Parameters benutzen. Also z.B.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
void FunktionA (CPlayer* a)
{
  a->AktionXY ();
}

int main()
{
   /* ... */
   CPlayer* pPlayer = new CPlayer (...);

   FunktionA (pPlayer);
   /* .... */
}
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

Netzwerkbibliothek von mir, C#, LGPL: https://sourceforge.net/projects/statetransmitt/

Tankard

Treue Seele

Beiträge: 192

Beruf: Student, Hardware- und Softwareentwicklung als wissenschaftliche Hilfskraft

  • Private Nachricht senden

3

09.02.2014, 17:23

Der Pointer ist eine ganz normale Variable, die du rumschieben kannst wie du willst.

Bevor du aber jetzt anfängst und wirklich Pointer benutzt, solltest du dir unbedingt Smart Pointer angucken!

4

09.02.2014, 17:36

Danke für die Antworten. SmartPointer schaue ich mir mal an :)

Ich glaube ich bin wirklich auf den Holzweg. Ich erkläre einmal was ich wirklich vor habe.

Funktion 1 - Charaktererstellung:

Es gibt eine Funktion die eine Klasse des Characters erstellen soll. Sie legt die Werte usw fest. Jetzt wird eine eine Klasse mit dem Namen Spieler erstellt. Diese kann ich innerhalb der Funktion hervorrangend bearbeiten.

Aber:

Funktion 2..3...4 und wie viele noch:
Hier habe ich keinen Zugriff mehr auf diese Klasse. Natürlich könnte ich sie Global erstellen. Aber schön ist das nicht.

Ich möchte in diesen Funktionen also Zugriff auf die bereits erstellte Klasse namens Spieler erhalten. Das geht so leider nicht. Ich dachte mit dem vorgehen wie oben wäre das eine Idee. Jedoch komme ich auch da nicht an die Daten.

Parameterübergabe habe ich noch nicht versucht. Ich denke jedoch, dass eine Übergabe via Parameter nicht gerade sinn macht da nicht jede der Funktionen in die Funktion der Charaktererstellung mit eingebunden werden soll. Sie haben also eigentlich keinen Kontakt mit Funktion 1. Komme ich trotzdem irgendwie an die Klasse "Spieler" um Funktionen oder Werte von Ihre abzurufen?

ein einfaches Klasse Spieler->Funktion(); reicht leider nicht aus und führt zu Fehlermeldungen auch wenn der Compiler nicht meckert :/.

Danke noch einmal

Cookiezzz

Frischling

Beiträge: 91

Wohnort: Deutschland

Beruf: Schüler

  • Private Nachricht senden

5

09.02.2014, 18:38

Hi,
also erstmal, es wird keine neue Klasse erstellt, sondern höchstens eine Instanz einer bereits existierenden Klasse. Nach deinem new-Aufruf zeigt dein Zeiger aud diese Instanz; wenn du von woanders darauf zugreifen willst, musst du den Zeiger durchreichen. Woher sollen deine anderen Funktionen sonst wissen, wo sich deine gerade erstellte Instanz im Speicher befindet? Schließlich kann es ja auch mehrere Objekte des gleichen Typs geben.
Den Zeiger global zu machen ist allerdings wirklich eine schlechte Idee. Besser wäre es jedoch, ihn in einem Objekt einer anderen Klasse zu speichern, die ihn braucht. Also im Prinzip folgendermaßen:


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
class Game
{
private:
   Player* _Player; //Der Zeiger auf deinen Spieler
   // ... weitere Variablen...
public:
   Game(void)
   {
       _Player = new Player(/* ... Parameter zum erzeugen vom Player ...*/);
   }
   ~Game(void)
   {
      delete _Player; //Freigeben nicht vergessen!
   }
   void deineFunktion()
   {
      //Mach was du willst mit _Player...
      _Player->die();
   }
   void deineFunktion2()
   {
      //Mach was du willst mit _Player...
     int health = _Player->getHealth(); //usw...
   }
};


Von außen kannst du jetzt mithilfe der Funktionen indirekt auf deinen Spieler zugreifen. Wenn die Klasse des Spielers unterschiedlich sein soll, kann man auch einen Zeiger an den Konstruktor übergeben, der dann damit _Player füllt. Auch die Verwendung von Samrtpointern wäre hier sinnvoll.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

09.02.2014, 19:28

Wahlweise:

C-/C++-Quelltext

1
2
3
4
5
6
7
Player* createPlayer() { return new Player(...); }

void blaBlub(Player* player) { player->whatever(); }

...
auto player = createPlayer();
blaBlub(player);


Parameter und Rückgabewerte sind ein wichtiges Grundlagenthema.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

7

09.02.2014, 19:46

Ich glaube ich bin gerade zu dumm dazu xD

Aber danke für die Antworten.

ich poste einmal den Code vereinfacht:

Klassen.hpp:

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class CPlayer {
private:
    // Membervariables
    // Hier stehen dann die Variablen
public:

    // Konstruktor
    // Aufgabe: erstellt den Spieler
    //
    CPlayer() {


        // Variablen
        //
        // Auch die die Variablen entfernt um es einfach zu machen

        cout << "Name des Spielers: ";
        cin >> m_cName;
        cout << endl;

        // Spieler erstellen

        CPlayer* _pPlayer = NULL;
        _pPlayer = new CPlayer;
        cout << "Health: " << endl; // Das sind Beispiele zum Aubrufen der Health // das ist zum test ob es klappt.
        ShowHealth(); // hier eine Funktion die wiederum einfach erstmal den Zugriff testen soll


    } // Konstruktor


    // Memberfunktionen
    //
    void ShowHealth() {
    cout << m_iHealth << endl;
    }; // Health anzeigen

    // Dekonstruktor     // Hier liegt z.B. ein Problem. Wie delete ich hier?
    // Aufgabe: Töten den Spieler und Räumt auf.
    //
    ~CPlayer() {
        cout << "Der Spieler ist tot!" << endl;
    } // Dekonstruktor

};



Hier ein Auszug der main.cpp um zu Zeigen wie der Spieler derzeit erstellt wird. Die #include 's sind natürlich drin

C-/C++-Quelltext

1
CPlayer Spieler;


Mein Problem ist also folgendes:

1.) Wie gebe ich den reservierten Speicher mittels des Dekonstruktors wieder frei (delete)?
2.) Wie Greife ich auf die Instanz (Danke für das Wort) zu? Wenn ich z.B. Werte ändern möchte.

In einer großen Datei könnte ich es schreiben. Aber leider nicht wenn ich es in .hpp und .cpp Dateien gliedere :/. Genau da liegt mein Experiment. Möchte genau das schaffen :)

Ich Verfüge leider nur über begrenztes wissen in Sachen C++. Arbeite zzt. das Buch von Heiko Kalista druch. C++ für Spieleprogrammierer. Dort finde ich aber leider keinen Part der das erklärt. Oder ich übersehe es :).
Die Sache mit den Klassen habe ich bereits durch. Das wird dort aber nicht erklärt.

Danke

Gruß

Rok

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »R0kn1x« (09.02.2014, 19:56)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

8

09.02.2014, 20:09

Siehe Antwort von Cookiezzz.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

9

09.02.2014, 20:45

Hi

verstehe ich es richtig? Ich mache also 2 Klassen?

10

09.02.2014, 21:13

new CPlayer bedeutet, dass auf dem Heap Speicher in der Größe eines CPlayer-Objekts reserviert wird und dann dort eine Instanz der Klasse mittels des Konstruktors initialisiert wird.
Das tust du natürlich an der Stelle, an der du ein solches Objekt auch benötigst und nicht im Konstruktor der Klasse selber. Dein Code führt momentan nur zur endlosen Rekursion von Konstruktoraufrufen der CPlayer-Klasse.

Im Beispiel von Cookiezzz siehst du wie eine Klasse, die ein CPlayer-Objekt benötigt, dieses auf dem Heap anlegt und damit arbeitet. Für die Implementierung von CPlayer selber ist es erstmal egal, ob Instanzen später auf dem Stack oder auf dem Heap erzeugt werden.

In deinem Code wäre also die korrekte Stelle für ein CPlayer* Spieler = new CPlayer; in der main.cpp, wo momentan noch CPlayer Spieler steht, was bedeutet, dass hier eine Instanz von CPlayer auf dem Stack angelegt wird.

Hier wird das auch nochmal erklärt: http://de.wikibooks.org/wiki/C++-Program…_new_und_delete
Generell empfiehlt sich mittlerweile aber auch wirklich die Verwendung der Smart Pointer.

Werbeanzeige