I don't like static data members much, the problem of initialization being foremost.
Whenever I have to do significant processing, I cheat and use a local static instead:
class MyClass
{
public:
static const SomeOtherClass& myVariable();
};
const SomeOtherClass& MyClass::myVariable()
{
static const SomeOtherClass MyVariable(someOtherFunction());
return MyVariable;
}
This way, the exception will be throw only on first use, and yet the object will be const.
This is quite a powerful idiom to delay execution. It had a little overhead (basically the compiler checks a flag each time it enters the method), but better worry about correctness first ;)
If this is called from multiple threads:
- if your compiler handles it, fine
- if your compiler does not, you may be able to use local thread storage (it's const anyway)
- you could use
boost::once in the Boost.Threads library
- since it's
const, you may not care if it's initialized multiple times, unless someOtherFunction does not support parallel execution (beware of resources)
Guideline: only use static or global variables instantiation for simple objects (that cannot throw), otherwise use local static variables to delay execution until you can catch the resulting exceptions.