Использование Singleton в разных классах - PullRequest
2 голосов
/ 20 августа 2010

Как создать экземпляр синглтона, который можно использовать в других классах?

Например:

//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(){};
};

Я получаю ошибку компоновки при попытке включить заголовок одного класса для класса A (LNK2005): «private: статический класс Singleton Singleton :: _ instance» (? _Instance @ Singleton @@ 0V1 @ A) уже определен в классе Singleton .obj

Ответы [ 2 ]

7 голосов
/ 20 августа 2010

Вам необходимо определить переменную экземпляра в одном из ваших исходных (.cpp) файлов, а не в файле заголовка.

Если переменная экземпляра определена в файле заголовка, то когда этот файл заголовкавключенный в несколько исходных файлов, он заканчивается определением несколько раз (именно об этом говорит ошибка).

6 голосов
/ 20 августа 2010

Джеймс уже говорил вам, в чем проблема: вам нужно переместить определение переменной static в отдельный файл .cpp.

Если вы не хотите иметь файл .cpp только для переменной, вы можете сделать его локальным static для функции getInstance():

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

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

Это означает ленивую инициализацию, хотя. Обычно это нормально, но иногда вам нужно инициализировать объект до main().

Если у вас есть такая проблема, возможно, вы могли бы поместить переменную экземпляра в шаблон класса:

// 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;}
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...