FAQ 16.15 What is a simple and robust solution to the static initialization order problem?

A very simple and fairly robust solution is to change the static data member into a static member function that returns a reference to a dynamically allocated object. This provides construct on first use semantics, which is desirable in many situations.

The following code shows how to apply this technique to the example from the previous FAQ. The static data member Wilma Fred::wilma_ has been changed to a static member function, Wilma& Fred::wilma(), and all uses of Fred::wilma_ have been changed to Fred::wilma(). Class Wilma is not shown since it is unchanged from the example in the previous FAQ.

 class Fred { public:   Fred() throw(); protected:   static Wilma& wilma() throw();                     <-- 1 }; inline Fred::Fred() throw() {   cout << "Fred ctor\n";   wilma().f();                                       <-- 2 } Fred x; Wilma& Fred::wilma() throw()                         <-- 3 {   static Wilma* p = new Wilma();                     <-- 4   return *p; } 

(1) Used to be static Wilma wilma_;

(2) Used to be wilma_.f()

(3) Used to be Wilma Fred::wilma_;

(4) Don't forget the "static"!

In the static member function Fred::wilma(), pointer p is static, so the new Wilma() object is allocated only the first time that Fred::wilma() is called. All subsequent calls simply return a reference to the same Wilma object.

As shown in the (annotated) output from this program, the Wilma object is initialized before it is used. This is good.

 Fred ctor Wilma ctor                                           <-- 1 Wilma used                                           <-- 2 

(1) The static object is constructed

(2) The static object is used



C++ FAQs
C Programming FAQs: Frequently Asked Questions
ISBN: 0201845199
EAN: 2147483647
Year: 2005
Pages: 566
Authors: Steve Summit

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net