More C++ Idioms/Construct On First Use

Construct On First UseEdit

IntentEdit

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 AsEdit

Lazy construction/evaluation

MotivationEdit

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 f;
Bar Foo::bar_;
 
int main () {}

In the above code, Bar::f() gets called before its constructor. It should be avoided.

Solution and Sample CodeEdit

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 UsesEdit

  • 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.

Related IdiomsEdit

ReferencesEdit

Last modified on 17 September 2012, at 16:57