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

Related Idioms[edit | edit source]

References[edit | edit source]