// Purpose.  Singleton                  // New design.  "globalObj" is now a
 //                                      // private static data member of its
 // Discussion.  On the left, a global   // own class.  Global access is pro-
 // object is architected to require     // vided by the public static member
 // lazy initialization (not inited un-  // function inst().  And the lazy
 // til it is needed).  This requires    // initialization code is encapsu-
 // all users of the object to test and  // lated in the inst() function.
 // potentially allocate the pointer.    // GlobalClass's ctor and dtor have
 // Singleton suggests making the class  // been made protected so that cli-
 // itself responsible for creating,     // ents cannot create more inst's
 // maintaining, and providing global    // or destroy the Singleton inst.
 // access to its own single instance.
                                         class GlobalClass {
 #include <iostream.h>                   public:
                                            int  getValue() {
 class GlobalClass {                           return value_; }
 public:                                    void setValue( int v ) {
    GlobalClass( int v=0 ) {                   value_ = v; }
       value_ = v; }                        static GlobalClass* inst() {
    int  getValue() {                          if ( ! globalObj_ )
       return value_; }                           globalObj_ = new GlobalClass;
    void setValue( int v ) {                   return globalObj_; }
       value_ = v; }                     protected:
 private:                                   GlobalClass( int v=0 ) {
    int  value_;                               value_ = v; }
 };                                         ~GlobalClass() { }
                                         private:
 // Initializing a global ptr to class      int    value_;
 // GlobalClass                             static GlobalClass* globalObj_;
 GlobalClass*   globalObj = 0;           };

 void foo( void )                        // Allocating and initializing
 {                                       // GlobalClass's static data member
    if ( ! globalObj )                   // (the ptr, not a GlobalClass inst)
       globalObj = new GlobalClass;      GlobalClass*
    globalObj->setValue( 1 );               GlobalClass::globalObj_ = 0;
    cout << "foo: globalObj is " <<
       globalObj->getValue() << endl;    void foo( void )
 }                                       {
                                            GlobalClass::inst()->setValue( 1 );
 void bar( void )                           cout << "foo: globalObj is " <<
 {                                             GlobalClass::inst()->getValue()
    if ( ! globalObj )                         << endl;
       globalObj = new GlobalClass;      }
    globalObj->setValue( 2 );
    cout << "bar: globalObj is " <<      void bar( void )
       globalObj->getValue() << endl;    {
 }                                          GlobalClass::inst()->setValue( 2 );
                                            cout << "bar: globalObj is " <<
 void main( void )                             GlobalClass::inst()->getValue()
 {                                             << endl;
    if ( ! globalObj )                   }
       globalObj = new GlobalClass;
    cout << "main: globalObj is " <<     void main( void )
       globalObj->getValue() << endl;    {
    foo();                                  cout << "main: globalObj is " <<
    bar();                                     GlobalClass::inst()->getValue()
 }                                             << endl;
                                            foo();
 // main: globalObj is 0                    bar();
 // foo: globalObj is 1                  }
 // bar: globalObj is 2
                                         // main: globalObj is 0
                                         // foo: globalObj is 1
                                         // bar: globalObj is 2



 // Purpose.  Singleton destroyer        class GlobalClass;
 //
 // Discussion.  Vlissides describes     class SingDest {
 // that Singletons can be cleaned-up    public:
 // by "wrapping" the ptr in a stack-       SingDest( GlobalClass* s=0 ) {
 // based static member of another             sing_ = s; }
 // class whose sole responsibility is      ~SingDest();
 // to have its destructor delete the       void setSing( GlobalClass* s ) {
 // Singleton's ptr.  The Singleton            sing_ = s; }
 // destroyer is automatically cre-      private:
 // ated before main() is run, and          GlobalClass*  sing_;
 // initially contains a null ptr.       };
 // The first time the inst() method
 // is called, the destroyer is          class GlobalClass {
 // meaningfully initialized.            public:
                                            friend class SingDest;
 #include <iostream.h>                      int  getValue() { return value_; }
                                            void setValue( int v ) {
 class GlobalClass {                           value_ = v; }
 public:                                    static GlobalClass* inst() {
    int  getValue() {                          if ( ! globalObj_ ) {
       return value_; }                           globalObj_ = new GlobalClass;
    void setValue( int v ) {                      dest_.setSing( globalObj_ ); }
       value_ = v; }                           return globalObj_; }
    static GlobalClass* inst() {         private:
       if ( ! globalObj_ )                  GlobalClass( int v=0 ) {
          globalObj_ = new GlobalClass;        cout << ":ctor: ";
       return globalObj_; }                    value_ = v; }
 protected:                                 ~GlobalClass() {
    GlobalClass( int v=0 ) {                   cout << ":dtor:" << endl; }
       value_ = v; }                        int    value_;
    ~GlobalClass() { }                      static GlobalClass* globalObj_;
 private:                                   static SingDest dest_;
    int    value_;                       };
    static GlobalClass* globalObj_;
 };                                      GlobalClass*
                                            GlobalClass::globalObj_ = 0;
 // Allocating and initializing          SingDest GlobalClass::dest_;
 // GlobalClass's static data member     SingDest::~SingDest() { delete sing_; }
 // (the ptr, not a GlobalClass inst)
 GlobalClass*                            void foo( void ) {
    GlobalClass::globalObj_ = 0;            GlobalClass::inst()->setValue( 1 );
                                            cout << "foo: globalObj is " <<
 void foo( void ) {                            GlobalClass::inst()->getValue()
    GlobalClass::inst()->setValue( 1 );        << endl;
    cout << "foo: globalObj is " <<      }
       GlobalClass::inst()->getValue()   void bar( void ) {
       << endl;                             GlobalClass::inst()->setValue( 2 );
 }                                          cout << "bar: globalObj is " <<
 void bar( void ) {                            GlobalClass::inst()->getValue()
    GlobalClass::inst()->setValue( 2 );        << endl;
    cout << "bar: globalObj is " <<      }
       GlobalClass::inst()->getValue()   void main( void ) {
       << endl;                             cout << "main: globalObj is " <<
 }                                             GlobalClass::inst()->getValue()
 void main( void ) {                           << endl;
    cout << "main: globalObj is " <<        foo();
       GlobalClass::inst()->getValue()      bar();
       << endl;                             cout << "main: end" << endl;
    foo();                               }
    bar();
 }                                       // main: globalObj is :ctor: 0
                                         // foo: globalObj is 1
 // main: globalObj is 0                 // bar: globalObj is 2
 // foo: globalObj is 1                  // main: end
 // bar: globalObj is 2                  // :dtor:



 // Purpose.  Singleton (Scott Meyers    // New design.  "globalObj" is now a
 //                      approach)       // static variable in the inst() ac-
 // Discussion.  On the left, a global   // cessor method.  The single inst-
 // object is architected to require     // ance is enforced by declaring the
 // lazy initialization (not inited un-  // ctor non-public.  [The dtor must
 // til it is needed).  This requires    // be public because of the static
 // all users of the object to test and  // variable instance.]  Global
 // potentially allocate the pointer.    // access is provided by the static
 // Singleton suggests making the class  // inst() method.  The object is al-
 // itself responsible for creating,     // located on first demand by C++,
 // maintaining, and providing global    // and it is de-allocated automati-
 // access to its own single instance.   // cally by C++.

 #include <iostream.h>                   #include <iostream.h>

 class GlobalClass {                     class GlobalClass {
 public:                                 public:
    GlobalClass( int v=0 ) {                int  getValue() {
       value_ = v; }                           return value_; }
    int  getValue() {                       void setValue( int v ) {
       return value_; }                        value_ = v; }
    void setValue( int v ) {                static GlobalClass& inst() {
       value_ = v; }                           static GlobalClass globalObj;
 private:                                      return globalObj; }
    int  value_;                            ~GlobalClass() {
 };                                            cout << ":dtor:" << endl; }
                                         protected:
 // Initializing a global ptr to class      GlobalClass( int v=0 ) {
 // GlobalClass                                cout << ":ctor: ";
 GlobalClass*   globalObj = 0;                 value_ = v; }
                                         private:
 void foo( void )                           int  value_;
 {                                       };
    if ( ! globalObj )
       globalObj = new GlobalClass;      void foo( void )
    globalObj->setValue( 1 );            {
    cout << "foo: globalObj is " <<         GlobalClass::inst().setValue( 1 );
       globalObj->getValue() << endl;       cout << "foo: globalObj is " <<
 }                                             GlobalClass::inst().getValue()
                                               << endl;
 void bar( void )                        }
 {
    if ( ! globalObj )                   void bar( void )
       globalObj = new GlobalClass;      {
    globalObj->setValue( 2 );               GlobalClass::inst().setValue( 2 );
    cout << "bar: globalObj is " <<         cout << "bar: globalObj is " <<
       globalObj->getValue() << endl;          GlobalClass::inst().getValue()
 }                                             << endl;
                                         }
 void main( void )
 {                                       void main( void )
    if ( ! globalObj )                   {
       globalObj = new GlobalClass;         cout << "main: globalObj is " <<
    cout << "main: globalObj is " <<           GlobalClass::inst().getValue()
       globalObj->getValue() << endl;          << endl;
    foo();                                  foo();
    bar();                                  bar();
 }                                          cout << "main: end" << endl;
                                         }
 // main: globalObj is 0
 // foo: globalObj is 1                  // main: globalObj is :ctor: 0
 // bar: globalObj is 2                  // foo: globalObj is 1
                                         // bar: globalObj is 2
                                         // main: end
                                         // :dtor:



// Purpose.  Singleton design pattern

// 1. Define a private static attribute in the "single instance" class
// 2. Define a public static accessor function in the class
// 3. Do "lazy initialization" (creation on demand) in the accessor function
// 4. Define all constructors to be protected or private
// 5. Clients may only use the accessor function to manipulate the Singleton
// 6. Inheritance can be supported, but static functions may not be overridden.
//    The base class must be declared a friend of the derived class (in order
//    to access the protected constructor).

#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;

class Number {
public:
   static  Number* instance();      // 2. Define a public static accessor func
   static  void setType( string t ) { type = t;  delete inst;  inst = 0;}
   virtual void setValue( int in )  { value = in; }
   virtual int  getValue()          { return value; }
protected:
   int value;
   Number() { cout << ":ctor: "; }  // 4. Define all ctors to be protected
private:
   static string  type;
   static Number* inst;             // 1. Define a private static attribute
};

string  Number::type = "decimal";
Number* Number::inst = 0;

class Octal : public Number {       // 6. Inheritance can be supported
public:
   friend class Number;
   void setValue( int in ) {
      char buf[10];
      sprintf( buf, "%o", in );
      sscanf( buf, "%d", &value );
   }
protected:
   Octal() { }
};

Number* Number::instance() {
   if ( ! inst)
      // 3. Do "lazy initialization" in the accessor function
      if (type == "octal") inst = new Octal();
      else                 inst = new Number();
   return inst;
}

void main( void ) {
   // Number  myInstance; --- error: cannot access protected constructor
   // 5. Clients may only use the accessor function to manipulate the Singleton
   Number::instance()->setValue( 42 );
   cout << "value is " << Number::instance()->getValue() << endl;
   Number::setType( "octal" );
   Number::instance()->setValue( 64 );
   cout << "value is " << Number::instance()->getValue() << endl;
}

// :ctor: value is 42
// :ctor: value is 100