More C++ Idioms/Construct On First Use

From Wikibooks, open books for an open world
Jump to navigation Jump to search

Construct On First Use

Intent

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

Lazy construction/evaluation

Motivation

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 Code

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

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

References