More C++ Idioms/Construct On First Use
Construct On First Use
[edit | edit source]Intent
[edit | edit source]Ensure that an object is initialized before its first use. Specifically, ensure that non-local static object is initialized before its first use.
Also Known As
[edit | edit source]Lazy construction/evaluation
Motivation
[edit | edit source]Static objects that have non-trivial constructors must be initialized before they are used. It is possible to access an uninitialized non-local static object before its initialization if proper care is not exercised.
struct Bar {
Bar () {
cout << "Bar::Bar()\n";
}
void f () {
cout << "Bar::f()\n";
}
};
struct Foo {
Foo () {
bar_.f ();
}
static Bar bar_;
};
Foo foo;
Bar Foo::bar_;
int main () {}
In the above code, Bar::f() gets called before its constructor. It should be avoided.
Solution and Sample Code
[edit | edit source]There are 2 possible solutions, which depends upon whether the destructor of the object in consideration has non-trivial destruction semantics. Wrap the otherwise static object in a function so that function initializes it before it is used.
- Construct on first use using dynamic allocation
struct Foo {
Foo () {
bar().f ();
}
Bar & bar () {
static Bar *b = new Bar ();
return *b;
}
};
If the object has a destructor with non-trivial semantics, local static object is used instead of dynamic allocation as given below.
- Construct on first use using local static
struct Foo {
Foo () {
bar().f ();
}
Bar & bar () {
static Bar b;
return b;
}
};
Known Uses
[edit | edit source]- Singleton pattern implementations often use this idiom.
- ACE_TSS<T> class template in Adaptive Communication Environment (ACE) for creating and accessing objects in thread specific storage (TSS) uses this idiom.