3

我有这个:

单例.h

#ifndef SINGLETON_H
#define SINGLETON_H

#include <atomic>
#include <mutex>

class Singleton
{
public:
    static std::atomic<Singleton*> Singleton::m_instance;
    static std::mutex Singleton::m_mutex;
    static Singleton* getInstance();

    Singleton();
    ~Singleton();
};

#endif

单例.cpp

#include "Singleton.h"

Singleton::Singleton()
{
}

Singleton* Singleton::getInstance() 
{
    Singleton* tmp = m_instance.load(std::memory_order_relaxed);
    std::atomic_thread_fence(std::memory_order_acquire);
    if (tmp == nullptr) 
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        tmp = m_instance.load(std::memory_order_relaxed);
        if (tmp == nullptr) 
        {
            tmp = new Singleton;
            std::atomic_thread_fence(std::memory_order_release);
            m_instance.store(tmp, std::memory_order_relaxed);
        }
    }
    return tmp;
}

Singleton::~Singleton() {}

主文件

#include "Singleton.h"
#include <iostream>
int main()
{
    Singleton* singleton = Singleton::getInstance();
    std::cout << "Hello World!" << std::endl;
    return 0;
}

当我尝试构建时,我得到了这个错误(Visual Studios):

错误 1 ​​错误 LNK2001:无法解析的外部符号“public: static struct std::atomic Singleton::m_instance”(?m_instance@Singleton@@2U?$atomic@PAVSingleton@@@std@@A) c:...Singleton。对象单例

和:

错误 2 错误 LNK2001: 无法解析的外部符号“public: static class std::mutex Singleton::m_mutex” (?m_mutex@Singleton@@2Vmutex@std@@A) c:\Users\InusualZ\documents\visual ...Singleton .obj 单例

4

1 回答 1

4

您需要在源文件中定义静态成员变量,而不仅仅是在类定义中声明它们:

std::atomic<Singleton*> Singleton::m_instance;
std::mutex Singleton::m_mutex;

您可能有兴趣知道使用简单的局部静态变量可以实现几乎完全相同的惰性线程安全初始化:

Singleton* Singleton::getInstance() {
    static Singleton instance;
    return &instance;
}

这修复了内存泄漏,但如果您尝试从另一个静态变量的析构函数访问它,确实会引入潜在的死亡陷阱。没有办法在 C++ 中实现单例反模式而不会出现某种问题。您应该重新考虑单例是否适合您的设计。以我的经验,从来都不是。

于 2014-11-28T16:26:07.783 回答