Global & Static Classes

Started by
4 comments, last by Monkan 12 years, 1 month ago
Hey guys, I'm current working on my next game and I've made a couple so far but I've always felt that the code that I wrote for them is messy. I'm forever making every class global or static just so I can access them from somewhere else instead of having to pass refrences around. For example:


class EntityHandler
{
public:
void Tick();
void Draw();

static void AddNewEntity();
static void AddBullet();
private:
static vector<Bullet>BulletList;
static vector<Enemy>EnemyList;
};

I'm writing all of my classes like this just so I can add a new entity/bullet from anywhere in my code. Looking at I feel that it's correct, it works but I can't help thinking that it's just a bad way of programming.

I could just send a refrence to the EntityHandler to every class but the entities shouldn't have to know about that and I would also probably be sending in loads of other refrences to all the static classes I have just so I could perform 1 or 2 tasks. This isn't good but I honestly don't know how I could do it another way. I guess some sort of message/event system could work for this but I really don't know...

Anyway If anyone could point me in the right direction that would be awesome. Thanks
Advertisement
You are right in that it is not the best solution. You are also right in that giving each class reference to EntityHandler would be a bad idea as it requires boilerplate code and creates minor memory overhead.

A slightly better approach (although not the best imho) would be something like this:

class EntityHandler {
public:
void Tick();
void Draw();

void AddNewEntity();
void AddBullet();

private:
vector<bullet> BulletList;
vector<enemy> EnemyList;
};


class Global {
private:
static EntityHandler entityHandler;

public:
static EntityHandler& getEntityHandler();
};


This way at least EntityHandler is no longer static and its instances can be used elsewhere when required.

However, accessing Global::getEntityHandler() is a bit unwieldy and the rest of the code will become dependent on global instances.
The solution I usually prefer is to instead have a non-static class and pass its reference on only to methods that actually need it:

class EntityHandler {
public:
void Tick();
void Draw();

void AddNewEntity();
void AddBullet();

private:
vector<bullet> BulletList;
vector<enemy> EnemyList;
};

class Bullet {
public:
// Pass the reference of EntityHandler only to methods that actually require it
// or some other class containing EntityHandler reference.
// This way you won't have to worry about EntityHandler being destroyed before bullet as it would be generally
// passed from EntityHandler::Tick/Draw method.
// It would also be completely painless to take a Bullet from one EntityHandler and put it to another as there
// is no internal reference.
void Tick(EntityHandler& e);
void Draw(EntityHandler& e);
};


It might seem to be a bit of a hassle to pass it on to such functions, but there are generally quite few functions that should need to see something as grand as EntityHandler.
I never thought of passing the EntityHandler down through like that /facepalm.. So I could for example do this?


class Bullet {
public:
void Tick(EntityHandler& e);
void Draw(EntityHandler& e);
};

void EntityHandler::Tick()
{
vector<bullet>::Iterator it;
for(it = BulletList.begin(); it != BulletList.end(); it++)
{
(*it)->Tick(*this);
}
}

Precisely. I didn't write that part down before, but that is exactly what I meant.

Precisely. I didn't write that part down before, but that is exactly what I meant.


I started re-writing some of the static classes to pass the EntityHandler down and other classes and it works well. Thanks for the help!
Also don't forget about namespaces, I never used to use them and now use them everywhere, they are really handy for wrapping things up and making it all a bit neater.

"To know the road ahead, ask those coming back."

This topic is closed to new replies.

Advertisement