如何实现一个单例类
1、传统单例类实现方式
- 删除构造函数,拷贝构造函数
- 实现获取某个单例类的静态函数
- 提供唯一访问入口
class Singleton{
private:
Singleton();
Singleton(const Singleton& other);
public:
static Singleton* getInstance();
static Singleton* m_instance;
};
Singleton* Singleton::m_instance=nullptr;
//线程非安全版本
Singleton* Singleton::getInstance() {
if (m_instance == nullptr) {
m_instance = new Singleton();
}
return m_instance;
}
//线程安全版本,但锁的代价过高
Singleton* Singleton::getInstance() {
Lock lock;
if (m_instance == nullptr) {
m_instance = new Singleton();
}
return m_instance;
}
//双检查锁,但由于内存读写reorder不安全
Singleton* Singleton::getInstance() {
if(m_instance==nullptr){
Lock lock;
if (m_instance == nullptr) {
m_instance = new Singleton();
}
}
return m_instance;
}
2、参考Java Spring实现一个单例
某个类是否是单例,既可以通过技术手段实现,亦可以通过某种约束手段实现,参见Java Spring中Bean的实现。我们仅创建一个该类的实例,作为单例使用, 参见如下代码。
-
定义单例基类
-
编写单例类继承自该基类
-
测试
#pragma once
#include <stdexcept>
template <typename T>
class Singleton {
public:
template<typename... Args>
static T* Instance( Args&&... args ) {
if ( m_pInstance == nullptr )
m_pInstance = new T( std::forward<Args>( args )... );
return m_pInstance;
}
static T* GetInstance( ) {
if ( m_pInstance == nullptr )
throw std::logic_error( "the instance is not init, please initialize the instance first" );
return m_pInstance;
}
static void DestroyInstance( ) {
delete m_pInstance;
m_pInstance = nullptr;
}
private:
static T* m_pInstance;
};
template <class T> T* Singleton<T>::m_pInstance = nullptr;
class BoardManager : public Singleton<BoardManager>
{
private:
string m_configureFile;
uint32_t m_slotCount;
public:
BoardManager(string configureFile = "", uint32_t slotCount = 0)
: m_configureFile(configureFile), m_slotCount(slotCount)
{
}
int32_t Initialize()
{
cout << "Initialize called" << endl;
}
void Destroy()
{
cout << "Destroy called" << endl;
}
};
int main()
{
//创建该类
BoardManager::Instance("C:\\configure.json", 2);
//获取该单例
BoardManager* boardManagerA = BoardManager::GetInstance();
BoardManager* boardManagerB = BoardManager::GetInstance();
//判断是否是同一个对象
std::cout << boolalpha << (boardManagerA == boardManagerB) << endl;
//BoardManagerB& a = BoardManagerB::Instance();
//BoardManagerB& b = BoardManagerB::Instance();
//std::cout << boolalpha << (a == b) << endl;
}