Singleton C ++模板类

时间:2012-07-12 13:20:32

标签: c++ templates singleton

  

可能重复:
  Why can templates only be implemented in the header file?

我意识到在SO上已经很少有这样的话题,但是我找不到任何可以解决我问题的话题。

我已经使用本教程http://www.codeproject.com/Articles/4750/Singleton-Pattern-A-review-and-analysis-of-existin

编写了我的模板单例类

但不幸的是我继续犯错:

  

/home/USER/testcode/cpp_workshop/main.cpp:-1:错误:未定义   引用`Singleton :: Instance()': - 1:error:collect2:ld

my singleton.h

#ifndef SINGLETON_H
#define SINGLETON_H

template <typename T>
class Singleton
{
public:
    static T& Instance();

protected:
    virtual ~Singleton();
    inline explicit Singleton();

private:
    static T* _instance;
    static T* CreateInstance();
};

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

#endif // SINGLETON_H

singleton.cpp

#include "singleton.h"
#include <cstdlib>

template <typename T>
Singleton<T>::Singleton()
{
    assert(Singleton::_instance == 0);
    Singleton::_instance = static_cast<T*>(this);
}

template<typename T>
 T& Singleton<T>::Instance()
{
    if (Singleton::_instance == 0)
    {
        Singleton::_instance = CreateInstance();
    }
    return *(Singleton::_instance);
}

template<typename T>
inline T* Singleton<T>::CreateInstance()
{
    return new T();
}

template<typename T>
Singleton<T>::~Singleton()
{
    if(Singleton::_instance != 0)
    {
        delete Singleton::_instance;
    }
    Singleton::_instance = 0;
}

这就是我如何称呼它(使用normall - 没有模板或任何东西 - 类GameSingleton<Game>::Instance().run();

3 个答案:

答案 0 :(得分:3)

将您的方法定义放在标题中的类定义下,并删除您的cpp。必须在标题中定义模板化类的模板化方法和方法(有几个例外)。

根据请求,以下是“hackish例外”:

  • 1)请参阅@Desmond Hume的回答
  • 2)仅使用定义方法的cpp中的模板化类。例如,您可以在cpp中的未命名命名空间中声明/定义模板化类,这很好。

答案 1 :(得分:2)

您可以将Singleton类的定义放入头文件,您可以保持声明(标题)和定义(.cpp文件)的分离,因为它是现在,如果您更喜欢它并且使用您要使用的每种类型显式实例化 Singleton类。要显式实例化Singleton类,请尝试将以下内容放在.cpp文件的末尾:

template
class Singleton<Game>;

使用另一种类型时,它会以同样的方式显示:

template
class Singleton<AnotherGame>; // just for example

答案 2 :(得分:0)

无法分离模板类的定义(头文件)和实现(cpp)。 所以你有两个解决方案之一:

1-实现头文件中的所有内容.h。像这样的东西

template <typename T>
class Singleton
{
public:
    static T& Instance(){}

protected:
    virtual ~Singleton(){}
    inline explicit Singleton(){}

private:
    static T* _instance;
    static T* CreateInstance(){}
};

另一种解决方案是将.cpp类重命名为.hpp。不要在.hpp文件中包含.h文件,反之亦然。即在.h文件中包含.hpp文件

我个人更喜欢第一种解决方案

干杯