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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…