头文件中的c++模板单例静态指针初始化

标签 c++ templates singleton static-members

头文件中的这个实现有什么问题?

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;

它有效,但我担心两件事:

  1. 静态成员应该在.cpp 文件中定义,以便在所有编译单元中只有一个实例,即使您将头文件包含到 10 个源文件中也是如此
  2. 指针被标准初始化为 NULL,为什么我需要显式初始化?

最佳答案

您可以通过在类定义之后添加 m_instance 成员的定义来修复您的错误。

template<typename T>
T* Singleton<T>::m_instance = nullptr;

对于类模板,可以在 header 本身中添加 static 成员的定义,并且不会导致 ODR 违规。

但是,正如其他人所建议的那样,最好将 getInstance() 定义更改为

static T& getInstance() 
{
    static T instance;
    return instance;
}

C++11 甚至保证函数局部 static 变量 instance 的创建将是线程安全的。

关于头文件中的c++模板单例静态指针初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23690416/

相关文章:

c++ - 通过模板化类中的成员函数返回不可修改的引用

java - 从接口(interface)创建全局唯一对象

c++ - 调试器看到的输出线程 ID

c++ - 将等式转化为 C++

c++ - 为什么我在 Eclipse IDE 中收到 "No binary found."错误?

singleton - EJB3 单例 session Bean 和 ConcurrentHashMap

javascript - 在 AngularJS 中创建一个工厂而不是 Singleton

c++ - 递归获取二叉搜索树的高度

c++ - 省略 C++ 模板参数列表时的区别

c++ - 模板类中的c++运算符重载Im正在尝试构建重载<<以打印树