我有这个:
Singleton.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
Singleton.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() {}
的main.cpp
#include "Singleton.h"
#include <iostream>
int main()
{
Singleton* singleton = Singleton::getInstance();
std::cout << "Hello World!" << std::endl;
return 0;
}
当我尝试构建时,我得到了这个错误(Visual studio):
错误1错误LNK2001:未解析的外部符号&#34; public:static struct std :: atomic Singleton :: m_instance&#34; (?m_instance @辛格尔顿@@ 2U?$ @原子@@@ PAVSingleton STD @@ A) c:...... Singleton.obj Singleton
和
错误2错误LNK2001:未解析的外部符号&#34; public:static class std :: mutex Singleton :: m_mutex&#34; (?m_mutex @ Singleton @@ 2Vmutex @ std @@ A)c:\ Users \ InusualZ \ documents \ visual ...... Singleton.obj Singleton
答案 0 :(得分:3)
您需要在源文件中定义静态成员变量,而不只是在类定义中声明它们:
std::atomic<Singleton*> Singleton::m_instance;
std::mutex Singleton::m_mutex;
您可能有兴趣知道使用简单的本地静态变量可以实现几乎完全相同的延迟线程安全初始化:
Singleton* Singleton::getInstance() {
static Singleton instance;
return &instance;
}
这可以修复内存泄漏,但如果您尝试从另一个静态变量的析构函数访问它,则会引入潜在的deathtrap。在没有某些问题的情况下,无法在C ++中实现Singleton反模式。你应该think again关于单身是否适合你的设计。根据我的经验,它永远不会。