static Vector in a GameObject Class

Started by
17 comments, last by taz0010 12 years, 5 months ago
I'm working with visual studio 2010 and I'm trying to create a GameObject class. In the class, there is a protected static vector which holds a collection of pointers to instances of the GameObject class. I've seen this done before in dev-c++, but I'm not sure how to get it to work with visual studio.

GameObject.h

#pragma once

#include <vector>
#include "SDL.h"

class GameObject
{

public:
GameObject(void);
~GameObject(void);

protected:
static std::vector<GameObject*> everything;
};


GameObject.cpp

#include "GameObject.h"


GameObject::GameObject(void)
{
everything.push_back(this);
}
Advertisement
Static members require a declaration in the CPP file.

GameObject.cpp

#include "GameObject.h"

std::vector<GameObject*> GameObject::everything

GameObject::GameObject(void)
{
everything.push_back(this);
}
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Using static objects in this way is not a very good idea. (See: Global Variables)

You're better off declaring the vector somewhere else and passing the reference in the GameObject constructor. One of the advantages here is you might later on decide you need to create multiple "everything" vectors (more likely than you think), in which case you'll be out of luck if it's a static member.

Thanks Promit, that fixed the compiling issues.

Taz, under what situation would having multiple everything vectors be useful? I'm new to the concept object oriented game programming, so I'm curious as to the other ways to lay out a engine.

Thanks Promit, that fixed the compiling issues.

Taz, under what situation would having multiple everything vectors be useful? I'm new to the concept object oriented game programming, so I'm curious as to the other ways to lay out a engine.


If you wanted to implement a save state/load state function. Which would generally be for testing purposes. Debugging game software is not an easy task, especially when games are typically designed to be unpredictable. A lot of bugs will be difficult to reproduce or require playing the game for a period of time before the opportunity to produce the bug comes up. Consider how useful it would be to be able to create copies of your game state at any point during execution, so you can test various functions in complete isolation from the rest of your game. If you can't run code in isolation, it becomes considerably harder to debug.

That being said, you mightn't have any problem using global state in *this* instance, but it's a habit that is often a root cause of unmaintainable software.



Using static objects in this way is not a very good idea. (See: Global Variables)


You've lost me on this comment. Other than having their point of initialization in common, I fail to see what commonality there is between statics and globals.

[quote name='taz0010' timestamp='1321080775' post='4883156']
Using static objects in this way is not a very good idea. (See: Global Variables)


You've lost me on this comment. Other than having their point of initialization in common, I fail to see what commonality there is between statics and globals.
[/quote]

What difference is there between:


int n;
namespace NS {
int n;
};
class C {
static int n;
};


the only difference is how you access it, C::n, NS::n, or just n. Either way you have global storage of data. In the class case you might be able to control it's visibility a little more, but it's still global data.

What difference is there between:


int n;
namespace NS {
int n;
};
class C {
static int n;
};


the only difference is how you access it, C::n, NS::n, or just n. Either way you have global storage of data. In the class case you might be able to control it's visibility a little more, but it's still global data.


Well, obviously there is no difference between ::n and NS::n, they're both namespace-level objects of static storage duration, one in the :: namespace and the other in the NS namespace. The only difference you could possibly point to is that they're in two different namespaces.

The class variable is a different kettle of fish. They way you have it declared, it is private to objects of static type C. Sure, it has static storage duration with all that entails, but since it does not entail a lot if you follow long-established conventions of grouping all related class functions in the same translation unit, order of construction is a non-issue (order of construction is well defined by the standard within a translation unit). I see nothing wring with class variables when they are appropriate: they solve a problem that is impossible to solve any better way.

Stephen M. Webb
Professional Free Software Developer

Having a static list of (presumably) all game objects indicates a poor design where the game objects check for collision themselves, etc. This often results in large, unweildly classes with lots of extraneous logic in them, often violating the Single Responsibility Principle and moving towards becoming god classes.

One design problem with this approach is that it is hard to unit test, because one cannot isolate instances of the class from this global list. One cannot set the state of this global list without exposing it to the rest of the application.

[quote name='luca-deltodesco' timestamp='1321235881' post='4883610']
What difference is there between:


int n;
namespace NS {
int n;
};
class C {
static int n;
};


the only difference is how you access it, C::n, NS::n, or just n. Either way you have global storage of data. In the class case you might be able to control it's visibility a little more, but it's still global data.

The class variable is a different kettle of fish. They way you have it declared, it is private to objects of static type C. Sure, it has static storage duration with all that entails, but since it does not entail a lot if you follow long-established conventions of grouping all related class functions in the same translation unit, order of construction is a non-issue (order of construction is well defined by the standard within a translation unit). I see nothing wring with class variables when they are appropriate: they solve a problem that is impossible to solve any better way.
[/quote]

Order of construction isn't what we're talking about, the fact is that the C::n var is still global data, and apart from it being 'hidden' outside the class, it is still global data.


This topic is closed to new replies.

Advertisement