views:

84

answers:

6

Static members confuse me sometimes. I understand how to initialize a simple built in type such as int with something along the lines of int myClass::statVar = 10;, which you place in a .cpp file, but I have something of the following sort:

class myClass
{
public:
 // Some methods...

protected:
 static RandomGenerator itsGenerator;
}

The basic idea is simple enough: myClass needs access to a random generator for one of its member functions. I also can have only a few instances of the generator since each object is quite big. However, the RandomGenerator type needs to be "initialized", so to speak, by a call to RandomGenerator::Randomize(), which the compiler won't allow you to do since it's not a const rvalue (is that right?).

So how can I make this work?

Or perhaps should I not make use of a static variable in this case, and do it some other way?

+3  A: 

You could create wrapper class which will hold RandomGenerator instance in it and will call RandomGenerator::Randomize in its constructor.

Kirill V. Lyadvinsky
+1  A: 

Put it in a private field, expose a static accessor. In the accessor, if the member is not yet initialized, initialize it.

onof
I'm banking towards this method. I think it may be the better solution, though wrapping the generator also seems like an elegant idea.
Kristian D'Amato
A: 

In cases such as these, singletons actually are your friends, despite their other drawbacks.

Pontus Gagge
A: 

Is it only a one function that needs RandomGenerator? You may do this in this way:

int myClass::foo() { static RandomGenerator itsGenerator = RandomGenerator::Randomize() ... }

gaspode
This wouldn't work because Randomize doesn't return a generator. Separating the lines would cause the generator to be randomized each time you enter the block.
Kristian D'Amato
+1  A: 

If RandomGenerator is copyable, you can use a helper function for initialization:

RandomGenerator init_rg() {
    RandomGenerator rg;
    rg.Randomize();
    return rg;
}

RandomGenerator myClass::itsGenerator = init_rg();
Georg Fritzsche
just be careful when initialising global (static) variables because ordering is not guaranteed.
doron
+1  A: 

Just write a function which returns a reference to a properly randomized RandomGenerator and turn itsGenerator into a reference to a generator:

class myClass
{
public:
 // Some methods...

protected:
 // make this a reference to the real generator
 static RandomGenerator& itsGenerator;
public:
 static RandomGenerator& make_a_generator() 
 {
   RandomGenerator *g=0;
    g=new RandomGenerator();
    g->Randomize();
   return *g;
 }
}

RandomGenerator& myClass::itsGenerator=myClass::make_a_generator();
Luther Blissett
Why so complicated if you can just return a stack-allocated instance and let NRVO take care of the rest or use a function-local `static` instance?
Georg Fritzsche
RandomGenerator needs an accessible copy constructor even with NRVO. I just wanted to avoid unnecessary requirements.
Luther Blissett