2

I'm currently developing an RPG game using C++ and I got to the point of including events on the map.

I wanted to be able to have the event on the map heal the player. I figured the easiest way to do this was to pass a pointer to the event object from the game using the 'this' keyword. When I got into doing this there were a whole bunch of compiler errors that seem to have resulted from trying to include a class that was currently attempting to include the other class. (endless loop I guess?)

For example. I have my 'game' class and it has a public member belonging to the 'mapManager' class. The 'mapManager' object then has the 'event' object as a member. The 'game' object also has a 'player' object within its' members. I need to have the 'event' object change variables that the 'player' has. I could honestly throw pointers whenever I need them but this might get cumbersome.

What I'm trying to ask is if there is an easy way to have a child of a parent access another child of that parent or if it would just be easier to throw pointers to all of the child classes needing them pointing to the other children.

Wow... that made very little sense but hopefully someone can understand enough to give me a good answer. Here's some code in case it helps.

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

Having just this results in "game does not name a type" and so I tried to include game in event.h and player.h and got the same error. What I want to do is be able to access player's variable HP from inside event.

Kethaias
  • 89
  • 1
  • 6
  • 1
    You sound in need of the observer design pattern. You'll need to show code and errors to get real help with your specific issue. – andre Sep 26 '12 at 20:22
  • I don't want to post my whole code because honestly it's way too messy and complicated. I made some sample code and I'm getting the same errors. I'll edit the question to include the code. – Kethaias Sep 26 '12 at 20:54

2 Answers2

3

It's preferable to avoid circular references where possible; however if you really want to do that, then the solution is to forward-declare your class Game at the top of the header files which will be using references/pointers to it. e.g.

#ifndef EVENTH
#define EVENTH

class Game;

class Event
{
    Game* game;
};

#endif

and..

#ifndef PLAYERH
#define PLAYERH

class Game;

class Player
{
    Game* game;
};

#endif

For header files which need no knowlege of the implementation/sizeof the Game class, a simple forward-declaration is sufficient to let the compiler know that a class with that name exists.

In your .cpp source files (where the implementation of Game is actually important and used by Player/Event implementation) you will still need to #include the header containing your Game class definition.

Ben Cottrell
  • 5,741
  • 1
  • 27
  • 34
2
//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);}
};

Don't make your event object change the player at all just make the event tell the player to heal himself. Also if game is suppose to represent everything then make it global.


To Answer the comment: (This is just my opinion and nothing else.)

After a bit of research i found this link that gives the names of great references.

The Definitive C++ Book Guide and List

Community
  • 1
  • 1
andre
  • 7,018
  • 4
  • 43
  • 75
  • While most of that makes perfect sense to me I'm now realizing just how little I know about the language itself. It may be asking a lot but is there any way you could point me towards a good book that covers the more advanced topics. I've gotten a few books but most don't go into detail on the more advanced things but rather just mention that they exist. Doesn't have to be books but that's my preference. I'd appreciate any help on that matter but you've done so much already that I understand if you would prefer not to. Thanks for everything you've done so far to help me. – Kethaias Sep 26 '12 at 22:14
  • @Kethaias: I answered your comment above. – andre Sep 27 '12 at 13:15
  • 1
    Don't use cplusplus.com. That website contain a lot of errors and promotes poor programming practices. –  Sep 28 '12 at 09:28
  • @jons34yp I'll change the link. Do you know a good reference site for stl containers and alogs? – andre Sep 28 '12 at 12:58
  • I usually use [cppreference.com](http://en.cppreference.com/w). BTW, don't refer to the C++ Standard Library as STL, STL is an _implementation_ of the C++ Standard Library by SGI. –  Sep 28 '12 at 22:12
  • @jons34yp Thanks for the insight, I still have a tone to learn myself. But instead of making a list of what I think would be nice I found a SO community thread answer. – andre Oct 04 '12 at 17:52