Communication between classes

Started by
6 comments, last by Glak 18 years, 8 months ago
Alright, I've run into a problem. I've finally started a project where I fully take advantage of what C++ can do as an object oriented language. This is turning out to be some of the most flexible code I've ever written. I've run into a snag, however. I'm using, for lack of a better term, a kind of "master class" to run my program: GameClass. Inside is the update, initialization, and shutdown functions. As one of the members, I'm using a linked list of GameObjects that are iterated through and updated both individually and against each other. Heres where my problem starts, though. I want these objects to have access to a few of the functions in GameClass. My first thought was to make a pointer in the objects that points to the GameClass, but I've got a kind of chicken and egg problem where I can't define a pointer to GameClass because the GameObject definition has to come first to be put on the linked list. My second thought was to add a kind of messaging system where an object can leave a message for the GameClass to read when it's iterated through. I can't help but see that as a messy hack, though, that would require too much work down the road to be worth it. My third thought was to make the objectlist global. I can imagine it working, but it seems like it might be a less elegant solution to the problem. Do you guys have any advice for me? I'm worried that my whole thought process went in the wrong direction a ways back.
Advertisement
If I'm understanding correctly, use a forward declaration before you declare your game objects, and before your game class, include the game object.

Example:
...class GameClass;class GameObject{...};
Quote:Original post by starstriker1
Heres where my problem starts, though. I want these objects to have access to a few of the functions in GameClass. My first thought was to make a pointer in the objects that points to the GameClass, but I've got a kind of chicken and egg problem where I can't define a pointer to GameClass because the GameObject definition has to come first to be put on the linked list.


You can define a pointer to an object without defining the object yet. Just write this:

class GameClass;


which is kind of like telling the compiler "okay, I promise that I'm going to define a class called GameClass". Then the compiler will let you make pointers to GameClass objects.
By the sounds of it the "master" GameClass could be a singleton, meaning that there is only ever one instanstiated version of it, and it's declarations could be something like:

GameClass.h

class GameClass{    private:       GameClass(){}       GameClass(const GameClass&);       GameClass& operator=(const GameClass&);            static GameClass* pGameClass;                public:       ~GameClass();                   static GameClass* Instance()       {            if (!pGameClass)            {                pGameClass= new GameClass;            }                            return pGameClass;      }                  void Free();                  int Initialize();      bool Update();      void Shutdown(ITask* t);   protected:      	               };


Include GameClass.h in the modules of your other classes and they can access the GameClass functions using the static Instance() function:

GameClass::Instance()->Initialize();

Of course you need to be able to free the memory that pGameClass points to so use the Free() function...which would look something like:

GameClass.cpp:
void GameClass::Free(){    delete pGameClass;}


As the Class is a singleton we should provide the default constructor (so the compliler doesn't make a public one for us), the copy constructor and the copy assignment operator as private declarations. No definitions are needed as all we are trying to do here is stop people making more than one copy of the class.

Just an idea...hope it gives you some food for thought..:)
Gary.Goodbye, and thanks for all the fish.
Since you're thinking about making GameClass a global, you could use a modified singleton approach to access it:
class GameClass {public:   static GameClass& getInstance() {      static GameClass instance_();      return instance_;   };private:   GameClass() {};   // constructors, assignments etc. are private   // ...   // class will be instantiated upon first call to getInstance()};

This will give you whatever access you need to expose, with the benefit of being able to control initialization order (it's a coin flip with a static global).

:stylin:

EDIT: to slow for you Gary :)
:stylin: "Make games, not war.""...if you're doing this to learn then just study a modern C++ compiler's implementation." -snk_kid
Thanks guys. I've got it now.

I used the trick the first two posters showed me, but I'll definitly look over the singleton idea. Thanks!
Cool.

As an extra bit of saftey it might be a good idea to set up an atexit() function that will ensure that the singleton(s)...and any extra bit of memory that might be hanging around are really freed.

The reason being that the Singleton design I presented will allocate memory to the pGameClass pointer whenever the Instance() member function is called, if pGameClass is null.

So, you might think you've freed up the singleton memory (by calling GameClass::Instance()->Free()) but another object might try to use the singleton class again, thereby reallocating memory to the pGameClass pointer, so using atexit() would help avoid this kind of memory leak.

Just another thought..:)
Gary.Goodbye, and thanks for all the fish.
"My third thought was to make the objectlist global. I can imagine it working, but it seems like it might be a less elegant solution to the problem."

The word "elegant" in programming/math means "simple". Some things are global from a design perspective so why not make them global in the implementation? At the very least make a global pointer as the previous poster mentioned.

The way I see it, if your program is just a game, it should have some game related global variables. Why put everything into a Game class, when the program itself is a game? Now if your program is also a word processor and ftp server then sure, put all of the game stuff into a Game namespace and so forth. Oh yeah, namespaces are your friend. I use them extensively.

This topic is closed to new replies.

Advertisement