C++中的单例模式一般分两种,一是饿汉单例模式,二是懒汉单例模式。其中懒汉单例模式本身保证线程安全,而饿汉单例模式需要加锁才能保证线程安全。并且,饿汉单例模式加锁后可以通过判断两次来提高性能,从而演化成双检测单例模式。下面用代码表达:
一、饿汉单例模式
Singleton_Eager.h
#pragma once
namespace Singleton_Eager
{
// 饿汉单例模式(保证线程安全)
class Singleton
{
private:
Singleton(void);
~Singleton(void);
public:
static Singleton* GetInstance();
private:
Singleton& operator=(const Singleton&);
static Singleton* m_Instance;
};
}
Singleton_Eager.cpp
#include "StdAfx.h"
#include "Singleton_Eager.h"
using namespace Singleton_Eager;
Singleton* Singleton::m_Instance = new Singleton();
Singleton::Singleton(void)
{
}
Singleton::~Singleton(void)
{
}
Singleton* Singleton_Eager::Singleton::GetInstance()
{
return m_Instance;
}
二、懒汉单例模式
Singleton_Lazy.h
#pragma once
namespace Singleton_Laze
{
// 懒汉单例模式(不保证线程安全,可以加锁)
class Singleton
{
private:
Singleton(void);
~Singleton(void);
public:
static Singleton* GetInstance();
private:
Singleton& operator=(const Singleton&);
static Singleton* m_Instance;
};
}
Singleton_Lazy.cpp
#include "StdAfx.h"
#include "Singleton_Lazy.h"
using namespace Singleton_Laze;
Singleton* Singleton::m_Instance = NULL;
Singleton::Singleton(void)
{
}
Singleton::~Singleton(void)
{
if (m_Instance != NULL)
{
delete m_Instance;
m_Instance = NULL;
}
}
Singleton* Singleton::GetInstance()
{
if (m_Instance == NULL)
{
m_Instance = new Singleton();
}
return m_Instance;
}
三、双检测单例模式
Singleton_Double.h
#pragma once
#include <Windows.h>
namespace Singleton_Doule
{
// 双检测单例模式,由饿汉单例模式演化而来
class Singleton
{
private:
Singleton(void);
~Singleton(void);
public:
static Singleton* GetInstance();
private:
Singleton& operator=(const Singleton&);
static Singleton* m_Instance;
static CRITICAL_SECTION m_cs;
};
}
Singleton_Double.cpp
#include "StdAfx.h"
#include "Singleton_Double.h"
using namespace Singleton_Doule;
Singleton* Singleton::m_Instance = NULL;
CRITICAL_SECTION Singleton::m_cs;
Singleton::Singleton(void)
{
}
Singleton::~Singleton(void)
{
}
Singleton* Singleton::GetInstance()
{
// 双检测保证
if (m_Instance == NULL)
{
InitializeCriticalSection(&m_cs);
EnterCriticalSection(&m_cs); //进入临界区
if (m_Instance == NULL)
{
m_Instance = new Singleton();
}
LeaveCriticalSection(&m_cs); //离开临界区
DeleteCriticalSection(&m_cs);
}
return m_Instance;
}
四、测试代码
SingletonTest.cpp
#include "StdAfx.h"
#include "Singleton_Double.h"
using namespace Singleton_Doule;
Singleton* Singleton::m_Instance = NULL;
CRITICAL_SECTION Singleton::m_cs;
Singleton::Singleton(void)
{
}
Singleton::~Singleton(void)
{
}
Singleton* Singleton::GetInstance()
{
// 双检测保证
if (m_Instance == NULL)
{
InitializeCriticalSection(&m_cs);
EnterCriticalSection(&m_cs); //进入临界区
if (m_Instance == NULL)
{
m_Instance = new Singleton();
}
LeaveCriticalSection(&m_cs); //离开临界区
DeleteCriticalSection(&m_cs);
}
return m_Instance;
}
五、后续
另外送你一个牛逼的用模板实现的单例模式:
Singleton.hpp
//
// Singleton模板
// 参考 boost 1-36-0/pool/detail/singleton.hpp
// 说明 http://www.yulefox.com/index.php/20081119/design-patterns-03.html/
//
#ifndef _SINGLETON_H_
#define _SINGLETON_H_
template <typename T>
struct singleton_default
{
public:
typedef T object_type;
static object_type& instance()
{
static object_type obj;
create_object.do_nothing();
return obj;
}
private:
struct object_creator
{
object_creator() { singleton_default<T>::instance(); }
inline void do_nothing() const {}
};
static object_creator create_object;
singleton_default();
};
template <typename T>
typename singleton_default<T>::object_creator
singleton_default<T>::create_object;
#define INSTANCE(class_name) singleton_default<class_name>::instance()
#endif // _SINGLETON_H_
使用示例:
INSTANCE(类名).方法();
六、参考文献
https://blog.csdn.net/woxiaohahaa/article/details/51344409
七、源码链接