静态类成员在动态库中与主应用程序不同

时间:2014-02-26 23:49:24

标签: c++ singleton static-members dynamic-library

我目前正在开发一个大量使用Singletons和动态库的应用程序(使用dlopen) 我的问题是我的单例在应用程序和动态库中的实例是不同的(即在我的实现中,Singleton :: getInstance方法返回不同的地址)

这就是我定义Singleton的方法

// Singleton.hpp
template<typename T>
class                   Singleton
{
  static T              *_instance;

protected:
  Singleton<T>() {}
  virtual ~Singleton<T>() {}

public:
  static T              *getInstance() {
    if (_instance == NULL)
      _instance = new T;
    return (_instance);
  }

  static void           deleteInstance() {
    if (_instance) {
      delete _instance;
      _instance = NULL;
    }
  }
};

template<typename T>
T                       *Singleton<T>::_instance = NULL;

然后,如果我想让一个类Test成为Singleton,我需要这样做:

// Test.hh
#include                   "Singleton.hpp"

class                      Test : public Singleton<Test>
{
  friend class             Singleton<Test>;

private:
  Test();
public:
  virtual ~Test();

  void                     doSomeStuff();
};

现在,如果我想使用Test,我会这样做:

#include                   "Test.hh"

int                        main() {
  Test                     *test = Test::getInstance();

  test->doSomeStuff();
  return (0);
}

为了解决这个问题,我尝试以某种方式“extern”(使用关键字)静态类成员Singleton :: _ instance,但我从未成功编译我的应用程序...... GCC拒绝那种代码(在Singleton中) .hpp)文件:

template<typename T>
extern T                   *Singleton<T>::_instance;

1 个答案:

答案 0 :(得分:1)

以下需要移出singleton.hpp。如上所述,它为每个.cpp文件创建一个指针实例,包括singleton.hpp。

template<typename T>
T                       *Singleton<T>::_instance = NULL;

请记住,这是一个定义,而不是声明。因此,包含头部的每个目标文件现在都定义了Singleton :: _ instance。如果多个.cpp文件包含singleton.h并在单个目标(可执行文件或库)中实例化具有相同类型的模板,则将获得多个定义的符号。

要使此代码更正,您需要选择单个.cpp文件(在单例模板的客户端中)并在那里定义_instance。这显然不是非常理想的,所以请考虑不使用单例(您的第一个,最佳选项)或使用不同的单例模式。