tags:

views:

74

answers:

2

How do you create a instance of a singleton that can be used in other classes?

For Example:

//Singleton_Class.h

#ifndef Singleton_Class
#define Singleton_Class

class Singleton
{
private: 
  static Singleton _instance;

  Singleton() {}
  ~Singleton() {} 
  Singleton(const Singleton &);
  Singleton & operator=(const Singleton &);

public:
 static Singleton &getInstance(){return _instance;}
};

Singleton Singleton::_instance;

#endif


//Main.cpp

#include "Singleton_Class.h"

int main()
{
    Singleton &s = Singleton::getInstance();  //Use the instance
}

//ClassA.cpp

#include "Singleton_Class.h"

class A
{
public:
 A(){};
};

I get a linking error when trying to include the single class header for class A (LNK2005): "private: static class Singleton Singleton::_instance" (?_instance@Singleton@@0V1@A) already defined in Singleton Class.obj

+5  A: 

You need to define the instance variable in one of your source (.cpp) files, not in the header file.

If the instance variable is defined in the header file, then when that header file is included in multiple source files, it ends up getting defined multiple times (which is what the error says).

James McNellis
+2  A: 

James already told you what the problem is: you need to move the definition of the static member variable into its own .cpp file.

If you don't want to have a .cpp file just for the variable, you could make it a local static to the getInstance() function:

class Singleton
{
private: 
  Singleton() {}
  ~Singleton() {} 
  Singleton(const Singleton &);
  Singleton & operator=(const Singleton &);

public:
  static Singleton &getInstance()
  {
    static Singleton _instance;
    return _instance;
  }
};

That means lazy initialization, though. Usually that's Ok, but sometimes you need the object to be initialized before main().

If you have that problem, maybe you could put the instance variable into a class template:

// Beware, brain-compiled code ahead!
template< typename S >
class SingletonBase
{
private:
  friend class Singleton;
  SingletonBase() {}
public:
  static S instance;
};

template< typename S >
S SingletonBase<S>::instance;

class Singleton : private SingletonBase<Singleton>
{
private: 
  Singleton() {}
  ~Singleton() {} 
  Singleton(const Singleton &);
  Singleton & operator=(const Singleton &);

public:
  static Singleton &getInstance(){return instance;}
};
sbi