Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ : Is it bad practice to use a static container in a class to contain pointers to all its objects for ease of access?

I would like to know if it's bad practice to have a static container in a class to store all the pointers to the class' objects so they can all be easily accessed by the base classes of the program. This is for a game and I saw it on sdltutorials dot com, and I find it very useful. It would allow me to have a very neat structure for my game and I don't really see a downside doing this, but I know I have to be careful with "global" access and maybe there's a negative effect I'm not seeing right now.

Here is the context/example. The game has a base class with basic methods such as Loop(), Render(), PlayAudio(), CleanMemory(). The idea is to have individual objects to have the same methods being executed inside the base method. Example in pseudocode:

Game::Render() {

  for (iterate all enemies in static container) {

     current_enemy::Render();
  }
}

To be sure, the static member inside the class would look like this:

static std::vector<Enemy*>    EnemyList;

So this way, when your game is executing the base Render() method, for example, you can iterate all the enemies in the enemies' class static container and execute all their individual Render() methods, then do the same for environment objects, then for the player, etc.

I would just like to make sure I'm aware of any downside/complication/limitation I might encounter if I choose this method to build my game, because I don't see any right now but I know a have to be careful with static and global stuff.

Thanks very much for your time.

like image 624
MajorScientist Avatar asked Dec 21 '25 23:12

MajorScientist


1 Answers

It is certainly convenient, however a static variable or a Singleton are nothing more than global variables; and having global variables comes with drawbacks:

  • the dependencies of a function become unclear: which global does it rely upon ?
  • the re-entrancy of a function is compromised: what if current_enemy.render() accidentally calls Game::Render() ? it's an infinite recursion!
  • the thread-safety of a function is compromised, unless proper synchronization takes place, in which case the serialized access to the global variable bog down the performance of your concurrent code (because of Amdahl's Law)

It might seem painful and pointless to explicitly pass a reference to an instance of Game wherever you need to, however it leaves a clear path of dependencies that can be followed and as the software grows you will appreciate explicitness.

And there is, of course, much to be said about transforming the program to have two instances of Game. While it might seem incongruous in this precise situation, in general it is wise not to assume that it will never be necessary in the future, for we are no oracles.

like image 117
Matthieu M. Avatar answered Dec 23 '25 14:12

Matthieu M.