Singleton C++ template class

Singleton C++ template class

本文关键字:class template C++ Singleton      更新时间:2023-10-16

可能重复:
为什么模板只能在头文件中实现?

我意识到SO上已经很少有这样的话题了,但我没有找到任何能回答我问题的话题。

我已经使用本教程编写了我的模板singleton类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:错误:collect2:ld

我的单身汉.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();

将方法定义放在头中的类定义下,然后删除cpp。模板化的方法和模板化类的方法必须在头中定义(有几个异常)。

根据请求,以下是"黑客异常":

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

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

template
class Singleton<Game>;

对于另一种类型,它看起来也一样:

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

不可能分离模板化类的定义(头文件)和实现(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文件

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

干杯