单例模式

来源:互联网 发布:政府网络不能玩皮皮 编辑:程序博客网 时间:2024/06/07 02:44
单例模式的作用:
1). 确保一个类只有一个实例被建立 
2). 提供了一个对对象的全局访问指针 
3). 在不影响单例类的客户端的情况下允许将来有多个实例

1.懒汉式

懒汉式的特点是延迟加载:

class Singleton{public:~Singleton() {}static Singleton* GetInstance(){if (nullptr == m_pInstance){m_pInstance = new Singleton();}return m_pInstance;}private:Singleton() {}static Singleton* m_pInstance;};Singleton* Singleton::m_pInstance = nullptr;

代码很简单,但是会存在内存泄漏的问题,new出来的东西始终没有释放,下面是一种懒汉式的一种改进:

class Singleton{public:class Clean{public:~Clean(){if (nullptr != m_pInstance){delete m_pInstance;m_pInstance = nullptr;}}};~Singleton() {cout<<"singleton destructor"<<endl;}static Singleton* GetInstance(){if (nullptr == m_pInstance){static Clean c;m_pInstance = new Singleton();}return m_pInstance;}private:Singleton() {cout<<"singleton constructor"<<endl;}static Singleton* m_pInstance;};Singleton* Singleton::m_pInstance = nullptr;


2.饿汉式

饿汉式的特点是一开始就加载了:

class Singleton{public:~Singleton() {cout<<"singleton destructor"<<endl;}static Singleton* GetInstance(){static Singleton instance;return &instance;}private:Singleton() {cout<<"singleton constructor"<<endl;}};

饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用;而懒汉式不是线程安全的。下面是多线程下的单例模式。

3.多线程下的单例模式
这里要处理的是懒汉模式。
class Singleton {private:Singleton() = default;static Singleton* m_pInstance;//定义一个内部类CLock,作用有两个://1.控制线程的安全//2.自动释放堆上的单例对象class CLock {public:CLock(){mutex = CreateMutex(NULL, FALSE, __FUNCTION__);}~CLock(){CloseHandle(mutex);if (m_pInstance)delete m_pInstance;}static void Lock() { WaitForSingleObject(mutex, INFINITE); }static void UnLock() { ReleaseMutex(mutex); }private:static HANDLE mutex;};public:static Singleton* GetInstance(){static CLock lock;//用来释放堆上的单例对象if (nullptr == m_pInstance) {CLock::Lock();if (nullptr == m_pInstance) {m_pInstance = new Singleton();}CLock::UnLock();}return m_pInstance;}};Singleton* Singleton::m_pInstance = nullptr;HANDLE Singleton::CLock::mutex = NULL;

4.通用的单例模式模板类

依靠C++11的可变模板参数的新特性,我们可以实现一个通用的单例模式的模板类:
#include <windows.h>#include <string>using namespace std;//单例模板类template <typename T>class Singleton {private:Singleton(void) = default;virtual ~Singleton(void) = default;Singleton(const Singleton&) = delete;Singleton& operator = (const Singleton&) = delete;static T* m_pInstance;//定义一个内部类CLock,作用有两个://1.控制线程的安全//2.自动释放堆上的单例对象class CLock {public:CLock(){string mutex_name = typeid(*this).name();mutex = CreateMutex(NULL, FALSE, mutex_name.c_str());}~CLock(){CloseHandle(mutex);if (nullptr != m_pInstance)delete m_pInstance;}static void Lock() { WaitForSingleObject(mutex, INFINITE); }static void UnLock() { ReleaseMutex(mutex); }private:static HANDLE mutex;};public://可变参数template<typename... Args>static T* GetInstance(Args&&... args){static CLock lock;//用来释放堆上的单例对象if (nullptr == m_pInstance) {CLock::Lock();if (nullptr == m_pInstance) {m_pInstance = new T(std::forward<Args>(args)...);}CLock::UnLock();}return m_pInstance;}};template <class T> T* Singleton<T>::m_pInstance = nullptr;template <class T> HANDLE Singleton<T>::CLock::mutex = NULL;class CMyClass1 {};class CMyClass2 {};int main(){//堆内存会自动释放,并且是线程安全的Singleton<CMyClass1>::GetInstance();Singleton<CMyClass2>::GetInstance();return 0;}

以上代码在VS2015下编译通过。
0 0
原创粉丝点击