设计模式学习笔记(单例模式)

来源:互联网 发布:q叔淘宝店叫什么名字 编辑:程序博客网 时间:2024/05/22 04:32

一、单例模式

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

单例模式是对全局变量的一种改进。全局变量空间利用率比较低,且在项目中是一个不安全隐患,特别是在多线程程序中,会有很多的不可预测性;同时,使用全局变量,也不符合面向对象的封装原则。

二、实例

1、基础版本:

#include <iostream>using namespace std;class Singleton{public:static Singleton *GetInstance(){if (m_Instance == NULL ){m_Instance = new Singleton ();}return m_Instance;}static void DestoryInstance(){if (m_Instance != NULL ){delete m_Instance;m_Instance = NULL ;}}int GetTest()//该函数用于测试{     return m_Test;}private:Singleton(){ m_Test = 10; }static Singleton *m_Instance;//一个静态成员变量,程序结束时,系统会自动调用它的析构函数int m_Test;};Singleton *Singleton ::m_Instance = NULL;int main(int argc , char *argv []){Singleton *singletonObj = Singleton ::GetInstance();cout<<singletonObj->GetTest()<<endl;Singleton ::DestoryInstance();return 0;}
但该版本没有考虑多线程情况。当我们运行在多线程环境的时候,静态变量的初始化来实现单件,是不可靠的――直接的说,静态变量有可能初始化多次!
2、改进版1(对版本1进行了改进,但仍然没解决多线程问题)

#include <iostream>using namespace std;class Singleton{public:static Singleton *GetInstance(){static Singleton m_Instance;//局部静态变量,非常强大的方法,完全实现了单例的特性,而且代码量更少,也不用担心单例销毁的问题。return &m_Instance;//返回的是一个指针,避免了问题}int GetTest(){return m_Test++;}private:Singleton(){ m_Test = 10; };int m_Test;};int main(int argc , char *argv []){Singleton *singletonObj = Singleton ::GetInstance();cout<<singletonObj->GetTest()<<endl;singletonObj = Singleton ::GetInstance();cout<<singletonObj->GetTest()<<endl;}

GetInstance函数如果返回引用,则Singleton singleton = Singleton :: GetInstance();这么做就出现了一个类拷贝的问题,这就违背了单例的特性。产生这个问题原因在于:编译器会为类生成一个默认的构造函数,来支持类的拷贝。


3、考虑线程安全

class Lock  {  private:             CCriticalSection m_cs;  public:      Lock(CCriticalSection  cs) : m_cs(cs)      {          m_cs.Lock();      }      ~Lock()      {          m_cs.Unlock();      }  };    class Singleton  {  private:      Singleton();      Singleton(const Singleton &);      Singleton& operator = (const Singleton &);    public:      static Singleton *Instantialize();      static Singleton *pInstance;      static CCriticalSection cs;  };    Singleton* Singleton::pInstance = 0;    Singleton* Singleton::Instantialize()  {      if(pInstance == NULL)      {   //double check          Lock lock(cs);           //用lock实现线程安全,用资源管理类,实现异常安全          //使用资源管理类,在抛出异常的时候,资源管理类对象会被析构,析构总是发生的无论是因为异常抛出还是语句块结束。          if(pInstance == NULL)          {              pInstance = new Singleton();          }      }      return pInstance;  }  



阅读全文
0 0