头文件中的此实现有什么问题?
template <typename T>
class Singleton
{
public:
static T* getInstance()
{
if (m_instance == NULL)
{
m_instance = new T();
}
return m_instance;
}
private:
static T* m_instance;
};
我这样用:
typedef Singleton<MyClass> MyClassSingleton;
我收到链接器错误:
error LNK2001: unresolved external symbol "private: static class MyClass * Singleton<class MyClass>::m_instance" (?m_instance@?$Singleton@VMyClass@@@@0PAVMyClass@@A)
当我添加
template <typename T> T* Singleton<T>::m_instance = NULL;
它有效,但我担心两件事:
答案 0 :(得分:10)
您可以通过在类定义后添加m_instance
成员的定义来修复错误。
template<typename T>
T* Singleton<T>::m_instance = nullptr;
对于类模板,可以在标题中添加static
成员的定义,但不会导致ODR违规。
但是,正如其他人所建议的那样,最好将getInstance()
定义更改为
static T& getInstance()
{
static T instance;
return instance;
}
C ++ 11甚至可以保证函数local static
变量instance
的创建是线程安全的。
答案 1 :(得分:3)
静态成员总是需要初始化一次,包括来自模板实例化的成员。
如果您真的喜欢,可以使用本地静态来避免这种情况:
template <typename T>
T *Singleton<T>::getInstance() {
// Will be lazy initialized on first call (instead of startup) probably.
static T instance;
return &instance;
}
或者:
// No need to use pointers, really...
template <typename T>
T &Singleton<T>::getInstance() {
static T instance;
return instance
};
答案 2 :(得分:2)
如果您真的想要使用单身,并且您确实想要使用模板化的单身,那么您可能想要使用Scott Meyer's singleton approach:
template <typename T>
class Singleton
{
public:
static Singleton<T>& getInstance() {
static Singleton<T> theInstance;
return theInstance;
}
private:
Singleton() {}
Singleton(const Singleton<T>&);
Singleton<T>& operator=(const Singleton<T>&);
};
答案 3 :(得分:2)
指针被标准初始化为NULL,为什么我需要 明确初始化?
你不需要。
template <typename T>
T* Singleton<T>::m_instance;
这就足够静态&amp;全局变量默认为零初始化
具有静态存储持续时间(3.7.1)或线程存储持续时间(3.7.2)的变量应为零初始化(8.5) 在进行任何其他初始化之前。
答案 4 :(得分:0)
其他人已经回答了如何修复代码,但你的问题也是关于推理的。作为解释,你正在努力的是声明和定义之间的区别。在这一行:
static T* m_instance;
您声明m_instance有一个名称,但您尚未定义该空间。您添加的代码行定义了空格。