c++singleton

Singletons via static instance in C++ -- into source or into header files?


Cheers,

I ran into this chunk of code in "Programming Game AI by Example":

/* ------------------ MyClass.h -------------------- */
#ifndef MY_SINGLETON
#define MY_SINGLETON

class MyClass
{
private:

  // member data
  int m_iNum;

  //constructor is private
  MyClass(){}

  //copy ctor and assignment should be private
  MyClass(const MyClass &);
  MyClass& operator=(const MyClass &);

public:

  //strictly speaking, the destructor of a singleton should be private but some
  //compilers have problems with this so I've left them as public in all the
  //examples in this book
  ~MyClass();

  //methods
  int GetVal()const{return m_iNum;}
  static MyClass* Instance();
};

#endif

/* -------------------- MyClass.cpp ------------------- */

//this must reside in the cpp file; otherwise, an instance will be created
//for every file in which the header is included
MyClass* MyClass::Instance()
{
  static MyClass instance;

  return &instance;
}

I am confused by the matter-of-fact statement by the author that the statically declared variable inside a function in header would result in declaring multiple, separate static variables instance. I don't think I've seen this behavior in my usual implementations of getInstance() function which I regularly put into headers (except that I like playing with pointers and initializing the singleton upon first use). I'm using GCC for my work.

So what does the standard say? What do non-compliant compilers say? Is the author's statement correct, and if so, can you name some compilers which would create multiple instances if getInstance() were declared in headers?


Solution

  • In C++ nothing prevent an inline function to have a static variable and the compiler has to arrange to make that variable common between all translation units (like it has to do it for template instantiation static class members and static function variables). 7.1.2/4

    A static variable in an extern inline function always refer to the same object.

    Note that in C, inline functions can't have static variables (nor reference to object with internal linkage).