Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 900
Ivan Vučica Avatar asked Sep 07 '09 13:09

Ivan Vučica


2 Answers

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

like image 193
AProgrammer Avatar answered Oct 21 '22 12:10

AProgrammer


I've tried the code that the OP posted with VS2008 in four ways and there doesn't seem to be a problem with the static instance of MyClass inside MyClass::Instance().

  1. Instance() is defined in MyClass.cpp: This is the normal way everything is fine.
  2. Instance() is defined only inside the class declaration. This is the alternative and everything is fine.
  3. Instance() is defined inline outside the class, but in the header and everything is fine.
  4. as 3. but without the inline and the linker says there are mutiple definitions of Instance()

I think that the book author is concerned with 4. above and knows that the static instance of MyClass will be taken care of in a program that compiles and links.

like image 43
quamrana Avatar answered Oct 21 '22 12:10

quamrana