Last modified on 17 September 2012, at 16:57

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