Дети, получающие доступ к элементам других детей того же родителя

В настоящее время я занимаюсь разработкой RPG-игры на C ++, и я решил включить события на карту.

Я хотел, чтобы событие на карте вылечило игрока. Я решил, что самый простой способ сделать это — передать указатель на объект события из игры, используя ключевое слово this. Когда я занялся этим, была целая куча ошибок компилятора, которые, по-видимому, возникли в результате попытки включить класс, который в настоящее время пытается включить другой класс. (бесконечный цикл, я думаю?)

Например. У меня есть свой класс игры, и у него есть открытый член, принадлежащий классу mapManager. Затем объект ‘mapManager’ имеет объект ‘event’ в качестве члена. Объект ‘game’ также имеет объект ‘player’ внутри своих ‘членов. Мне нужно иметь переменные объекта «событие», которые есть у «игрока». Я мог бы честно бросать указатели всякий раз, когда они мне нужны, но это может стать громоздким.

Я пытаюсь спросить, есть ли простой способ, чтобы дочерний элемент родительского элемента имел доступ к другому дочернему элементу этого родительского элемента, или было бы проще просто указывать указатели на все дочерние классы, где они должны указывать на других дочерних элементов. ,

Вау … это имело очень мало смысла, но, надеюсь, кто-то сможет понять достаточно, чтобы дать мне хороший ответ. Вот некоторый код на случай, если это поможет.


: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;
};

Из-за этого «игра не называет тип», поэтому я попытался включить игру в event.h и player.h и получил ту же ошибку. Я хочу получить доступ к переменной HP игрока изнутри события.

2

Решение

Желательно избегать циклических ссылок, где это возможно; Однако если вы действительно Если вы хотите сделать это, то решение состоит в том, чтобы объявить ваш класс вперед. Game в верхней части заголовочных файлов, которые будут использовать ссылки / указатели на него. например

#ifndef EVENTH
#define EVENTH

class Game;

class Event
{
Game* game;
};

#endif

а также..

#ifndef PLAYERH
#define PLAYERH

class Game;

class Player
{
Game* game;
};

#endif

Для заголовочных файлов, которые не нуждаются в знании реализации / размера Game class, простого forward-объявления достаточно, чтобы сообщить компилятору о существовании класса с таким именем.

В вашем .cpp исходные файлы (где реализация Game на самом деле важно и используется реализацией Player / Event) вам все еще нужно #include заголовок, содержащий определение вашего класса Game.

3

Другие решения

//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);}
};

Не заставляйте ваш объект события вообще менять игрока, просто заставьте событие сказать игроку, чтобы он исцелил себя. Также, если игра должна представлять все, сделайте ее глобальной.


Ответить на комментарий: (Это только мое мнение и больше ничего.)

После небольшого исследования я нашел эту ссылку, которая дает имена замечательных ссылок.

Полное руководство и список книг C ++

2

По вопросам рекламы [email protected]