2 Stimmen

Kinder, die auf Elemente von anderen Kindern desselben Elternteils zugreifen

Ich entwickle gerade ein RPG-Spiel mit C++ und bin zu dem Punkt gekommen, Ereignisse auf der Karte einzubauen.

Ich wollte, dass das Ereignis auf der Karte den Spieler heilen kann. Ich dachte, der einfachste Weg, dies zu tun war, um einen Zeiger auf das Ereignis-Objekt aus dem Spiel mit dem Schlüsselwort "this" übergeben. Als ich dies tat, gab es eine ganze Reihe von Compiler-Fehlern, die anscheinend aus dem Versuch resultierten, eine Klasse einzubinden, die gerade versuchte, die andere Klasse einzubinden. (Endlosschleife, nehme ich an?)

Zum Beispiel. Ich habe meine 'game'-Klasse und sie hat ein öffentliches Mitglied, das zur 'mapManager'-Klasse gehört. Das 'mapManager'-Objekt hat dann das 'event'-Objekt als Mitglied. Das "game"-Objekt hat auch ein "player"-Objekt in seinen Mitgliedern. Das 'event'-Objekt muss Variablen ändern, die der 'player' hat. Ich könnte ehrlich gesagt Zeiger werfen, wann immer ich sie brauche, aber das könnte umständlich werden.

Was ich versuche zu fragen, ist, wenn es eine einfache Möglichkeit, ein Kind eines Elternteils Zugriff auf ein anderes Kind dieses Elternteils haben, oder wenn es nur einfacher wäre, Zeiger auf alle Kind-Klassen zu werfen, die Sie auf die anderen Kinder verweisen müssen.

Wow... das machte sehr wenig Sinn, aber hoffentlich kann jemand genug verstehen, um mir eine gute Antwort zu geben. Hier ist etwas Code, falls es hilft.

:game.h

`

include "player.h" include "event.h"

class game { public: player Player; event Event; };

player.h

class player { public: game* Game;

};

event.h

class event { public: game* Game; };

`

Nachdem nur diese Ergebnisse in "Spiel nicht einen Typ benennen" und so habe ich versucht, Spiel in event.h und player.h einschließen und erhielt den gleichen Fehler. Was ich tun möchte, ist in der Lage sein, auf die Variable HP des Spielers von innerhalb des Ereignisses zuzugreifen.

3voto

Ben Cottrell Punkte 5513

Es ist vorzuziehen, Rundverweise nach Möglichkeit zu vermeiden; wenn Sie jedoch vraiment dies tun wollen, dann ist die Lösung, Ihre Klasse weiterzudeklarieren Game am Anfang der Header-Dateien, die Verweise/Zeiger darauf verwenden werden. z.B.

#ifndef EVENTH
#define EVENTH

class Game;

class Event
{
    Game* game;
};

#endif

und..

#ifndef PLAYERH
#define PLAYERH

class Game;

class Player
{
    Game* game;
};

#endif

Für Header-Dateien, die keine Kenntnis der Implementierung/Größe der Game Klasse ist eine einfache Vorwärts-Deklaration ausreichend, um den Compiler wissen zu lassen, dass eine Klasse mit diesem Namen existiert.

In Ihrem .cpp Quelldateien (wo die Implementierung von Game tatsächlich wichtig ist und von der Player/Event-Implementierung verwendet wird), müssen Sie noch #include die Kopfzeile mit der Definition Ihrer Spielklasse.

2voto

andre Punkte 6866
//game.h
class event;
class game {
    event _e;
private:
    game(){}
    //game& operator=(game& other) {}
    ~game(){}
public:
    static game & getInstance() {
        static game instance;
        return instance;
    }
    event& getEvent() {return _e;}
};

//HealEventObserver.h
class HealEventObserver {
public:
    virtual void heal() = 0;
    virtual ~HealEventObserver(){}
};

//player.h include game.h and HealEventObserver.h event.h
class Player : public HealEventObserver
{
public:
    virtual void heal() {/*heal the player*/}
    Player() {
        game& instance = game::getInstance();
        event& e = instance.getEvent();
        e.registerObserver(this);
    }
};

//event.h include HealEventObserver.h
class event {
    std::set<HealEventObserver*> _observers;
    void notify() {
        std::set<HealEventObserver*>::iterator it = _observers.begin();
        std::set<HealEventObserver*>::iterator end = _observers.end();
        for( ;it!=end; ++it) {
            it->heal();
        }
    }
public:
    void registerObserver(HealEventObserver* observer) {_observers.insert(observer);}
};

Lassen Sie Ihr Ereignisobjekt den Spieler überhaupt nicht verändern, sondern sagen Sie ihm nur, dass er sich heilen soll. Und wenn das Spiel alles darstellen soll, dann mach es global.


Um den Kommentar zu beantworten: (Dies ist nur meine Meinung und nichts anderes.)

Nach ein wenig Recherche habe ich diesen Link gefunden, der die Namen der besten Referenzen enthält.

Der definitive C++-Buchführer und die Liste

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X