Static variables

Hi

I’m in the process of learning C++ so please bear with me.

I’m making a particle system and want to alter the particle properties at runtime using ofxSimpleGuiToo. Here is the class structure:

-App
-ParticleManager
-Particle

The ofxSimpleGuiToo gui is set up in App. I need to be able to change the value of a variable in all instances of Particle from App. I’m mainly an Actionscript developer so in this case I would usually make the Particle properties static, this way I could change them from anywhere in the application. It seems that static or global variables in C++ don’t quite work the same way. Or do they?

I know I could place these variables in ParticleManager and pass them into each particle on update() but this doesn’t seem right, especially as there are several of them.

Any help would be much appreciated.

Jim

Ok… there are several ways to approach this…

The simplest approach (and probably the one most familiar to the static actionscript variables you described) would be to use global variables. Please note that for a number reasons, global variables are generally NOT recommended in most cases. In your case, what if you had several instances of your particle system, and wanted to manage the settings of each one individually?

A second approach would be to call a setMyValue method in your ParticleManager, and have your Particle objects query their manager for the value when they need it. This way, the value is centralized to one place. For this to work, you would need to make sure your Particle has a reference to its ParticleManager (ex. ParticleManager* myManager;), and then wherever you need to use the value, have the Particle call the ParticleManager’s getMyValue method.

A third approach would be to use a pointer for all the values in the Particle… Basically each Particle would have a pointer to the actual variable which would be stored in the ParticleManager or App itself… So then when you change the variable in one spot, because the variables in all the Particles are pointing to the same memory, it’s like they all get updated. This gets a little tricky in that when you initialize the Particle, you will need to make sure all its pointers get initialized to reference the correct variables.

If you are new to C++ and are already familiar with the fundamentals of programming… I would very strongly recommend learning about pointers. Do as many tutorials as it takes until you fully grok the how, when, and why of them… You will not regret it if you are to become a serious C++ programmer. I can’t stress how powerful pointers are in the C++ toolbox; but I will also say that they are notorious for being one of the trickiest concepts to grasp for C++ beginners.

Hope this helps! Let us know if you have any questions…

Thanks for your detailed response plong0. Looking into it now.

I’ve read about pointers but haven’t fully grasped the concept quite yet. I’m intending to move almost exclusively to C++ so I’ll definitely look further into the area.

Cool :slight_smile: You will still need to use pointers, but not as much as in the third approach.

I’m trying the second step but as soon as I include “ParticleManager.h” in the Particle.h there are errors in ParticleManager.h:

‘Particle’ was not declared in this scope

This happens when I try to declare the following vector in ParticleManager.h.

vector particles;

I think I can kind of see what is going wrong here. I’m including the ParticleManager header in Particle.h but ParticleManager.h already contains includes Particle.h. This is probably causing some sort of endless loop?

Also, how do I pass a reference of ParticleManager to Particle? I tried passing ‘this’ but it didn’t seem to work. Been Googling this like crazy but couldn’t find an answer.

Finially, is it best to ask non-OF specific questions like this on C++ forums? If so can you recommend one?

Ah yes… this is where cyclical references (ParticleManager -> Particle -> ParticleManager) get a bit dirty…

Basically you’ll want to set up your .h files like this:

ParticleManager.h

  
  
#ifndef _PARTICLE_MANAGER_H  
#define _PARTICLE_MANAGER_H  
  
#include "Particle.h"  
  
class ParticleManager{  
protected:  
  vector<Particle*> particles;  
  
public:  
  ParticleManager();  
  ~ ParticleManager();  
  
//  .... rest of ParticleManager code ...   
};  
  
#endif  
  

Particle.h

  
  
#ifndef _PARTICLE_H  
#define _PARTICLE_H  
  
class ParticleManager; // forward declaration of ParticleManager  
  
class Particle{  
protected:  
  ParticleManager* manager;  
  
public:  
  Particle(ParticleManager* manager){ this->manager = manager; };  
  ~Particle();  
  
};  
  
#include "ParticleManager.h" // now include the class definition of ParticleManager  
  
#endif  
  
  

And when you go to initialize a new Particle from within ParticleManager, you can do it like this:

  
  
Particle* newParticle = new Particle(this);  
this->particles.push_back(newParticle);  
  

Don’t forget to clean up that dynamic memory in ParticleManager’s destructor (or wherever else you are removing Particles) …

  
  
ParticleManager::~ParticleManager(){  
  this->clearParticles();  
}  
  
void ParticleManager::clearParticles(){  
  // loop through and clean up all the dynamically allocated memory  
  for(int i=0; i < this->particles.size(); i++){  
    Particle* cParticle = this->particles[i];  
    if(cParticle != NULL){  
      delete cParticle;  
      cParticle = NULL;  
    }  
  }  
  
  this->particles.clear(); // empty the vector  
}  
  

HTH!
-plong0

It worked! Thanks very much Plong0. Much appreciated.

Just out of interest, what was the second constructor with the ‘~’ in Particle.h and ParticleManager.h for?:

  
  
  ParticleManager();  
  ~ ParticleManager();  
  

I tried without the second one and the application still ran without a problem.

That’s a destructor. It is called automatically when a variable goes out of scope or is deleted.
You can (rather: should) use a destructor to free previously allocated memory, as e.g. in

  
  
// memory for one Particle instance is allocated  
Particle* newParticle = new Particle(this);  
this->particles.push_back(newParticle);  
  

When the particles-vector is cleared or goes out of scope, you lose the pointers to the memory that you have allocated. This memory is not accessible anymore but also not available any longer as long as your program is running. That’s a so-called memory leak. Your program gets larger and larger in memory until it blocks your whole system.

You could also call clearParticles() yourself, but the easier way is to let the destructor do the job.

Ah ok thanks for clearing that up for me. I’m using an object pool but that’ll definitely be useful in the future.