单例 C++ 模板类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11452760/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Singleton C++ template class
提问by Patryk
Possible Duplicate:
Why can templates only be implemented in the header file?
可能的重复:
为什么模板只能在头文件中实现?
I realise that there are already few topics like this on SO but I did not find any that would answer my problem.
我意识到在 SO 上已经很少有这样的主题了,但我没有找到任何可以回答我的问题的主题。
I have already written my template singleton class using this tutorial http://www.codeproject.com/Articles/4750/Singleton-Pattern-A-review-and-analysis-of-existin
我已经使用本教程编写了我的模板单例类http://www.codeproject.com/Articles/4750/Singleton-Pattern-A-review-and-analysis-of-existin
but unfortunately I keep on getting errors :
但不幸的是我不断收到错误:
/home/USER/testcode/cpp_workshop/main.cpp:-1: error: undefined reference to `Singleton::Instance()' :-1: error: collect2: ld
/home/USER/testcode/cpp_workshop/main.cpp:-1: 错误: 未定义对`Singleton::Instance()'的引用:-1: 错误: collect2: ld
my singleton.h
我的单身.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
单例.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;
}
and that's how I call it (with normall - not templated or anything - class Game
)
Singleton<Game>::Instance().run();
这就是我所说的(正常 - 不是模板化或任何东西 - 类Game
)
Singleton<Game>::Instance().run();
回答by David
Put your method definitions under your class definition in the header, and delete your cpp. Templated methods and methods of templated classes must be defined in headers (with a couple hackish exceptions).
将您的方法定义放在标题中的类定义下,然后删除您的 cpp。模板化方法和模板化类的方法必须在头文件中定义(有几个hackish 例外)。
Per request, here are the 'hackish exceptions':
根据请求,以下是“骇人听闻的例外”:
- 1) See @Desmond Hume's answer
- 2) Only use the templated class from the cpp in which the methods are defined. For example, you can declare/define a templated class in an unnamed namespace in a cpp, that's just fine.
- 1) 见@Desmond Hume 的回答
- 2) 仅使用定义方法的 cpp 中的模板化类。例如,您可以在 cpp 的未命名命名空间中声明/定义模板化类,这很好。
回答by Desmond Hume
You could put the definition of your Singleton
class into the header file oryou could keep the separation of declarations (the header) and definitions (the .cpp file) as it is now if you like it better and explicitly instantiatethe Singleton
class with each of the types you are going to use it with. To explicitly instantiate Singleton
class, try putting the following at the end of the .cpp file:
你可以把你的定义Singleton
类成头文件或者你可以继续申报(头)和定义(.cpp文件)的分离,因为它是现在,如果你喜欢它更好,显式实例的Singleton
与每类您将要使用它的类型。要显式实例化Singleton
类,请尝试将以下内容放在 .cpp 文件的末尾:
template
class Singleton<Game>;
With another type it would look in the same way:
对于另一种类型,它的外观相同:
template
class Singleton<AnotherGame>; // just for example
回答by Moataz Elmasry
Its not possible to separate the definiton (header file) and implementation (cpp) of a templated class. So you have one of two solutions:
无法将模板化类的定义(头文件)和实现(cpp)分开。所以你有两个解决方案之一:
1- implement everything in the header file .h. something like this
1- 在头文件 .h 中实现所有内容。像这样的东西
template <typename T>
class Singleton
{
public:
static T& Instance(){}
protected:
virtual ~Singleton(){}
inline explicit Singleton(){}
private:
static T* _instance;
static T* CreateInstance(){}
};
Another solution is to rename your .cpp class to .hpp. Don't include the .h file inside the .hpp file, but the other way around. i.e. include .hpp file inside .h file
另一种解决方案是将您的 .cpp 类重命名为 .hpp。不要在 .hpp 文件中包含 .h 文件,反之亦然。即在 .h 文件中包含 .hpp 文件
I personally prefer the first solution
我个人更喜欢第一个解决方案
Cheers
干杯