现在的位置: 首页 > 综合 > 正文

设计模式:21 单例模式

2018年05月18日 ⁄ 综合 ⁄ 共 2226字 ⁄ 字号 评论关闭

声明:VS2012中已经支持C++11了,因此下面的程序在VS2012中可以运行。如果版本比2012低,可能因为不支持:std::mutex,std::shared_ptr而失败。

 

 

#ifndef SINGLETON_H
#define SINGLETON_H
#include <memory>
#include <mutex>
using namespace std;

/*
关键:
1 双重检查机制:
  //先判断如果第一次创建,然后枷锁,然后在判断是否为空,实例化;如果一进入就加锁,那么效率不好;
  //如果判断完了再进入加锁,那么多个进程仍然会多次实例化,
  if(0 == _instance.get())
  {
   //锁定互斥量,在构造时锁定互斥量,析构时自动解锁,保证互斥量的正确操作
   std::unique_lock<std::mutex> uLock(_mutex);
   if(0 == _instance.get())

2     //防止实例化失败,C++中对指针赋值操作并不能保证原子操作,如果有某个线程1执行到这里,
    //赋值到一半,线程1挂起,线程2开始执行,这是_instance出于任何任何
    std::shared_ptr<T> temp(new T);
    _instance = temp;

3 友元类的使用:可以访问,Singleton类中声明friend class A;那么Singlton中的私有成员和变量可以被A类访问
#define DECLARE_SINGLETON_CLASS(type) \
 friend class shared_ptr< type >  ; \
 friend class Singleton< type > ;


*/

/*线程安全的单例模式,防止多个线程同时执行_instance.reset(new T);同时产生两个新的对象,
然后马上释放一个,这跟Singleton模式本意不符合*/
template<typename T>
class Singleton
{
private:
 Singleton(void){}
 Singleton(const Singleton& ){}
 ~Singleton(void){}
 Singleton& operator = (const Singleton& ){}
  
public:
 //static T* instance();
 static T* instance()
 {
  //先判断如果第一次创建,然后枷锁,然后在判断是否为空,实例化;如果一进入就加锁,那么效率不好;
  //如果判断完了再进入加锁,那么多个进程仍然会多次实例化,
  if(0 == _instance.get())
  {
   //锁定互斥量,在构造时锁定互斥量,析构时自动解锁,保证互斥量的正确操作
   std::unique_lock<std::mutex> uLock(_mutex);
   if(0 == _instance.get())
   {
    //防止实例化失败,C++中对指针赋值操作并不能保证原子操作,如果有某个线程1执行到这里,
    //赋值到一半,线程1挂起,线程2开始执行,这是_instance出于任何任何
    std::shared_ptr<T> temp(new T);
    _instance = temp;
   }
  }
  return _instance.get();
 }
private:
 static std::shared_ptr<T> _instance;//静态成员函数,指向该类的指针;注意这里定义的实际上是一个类型T的指针
 static std::mutex _mutex;         //独占对象
};

template<typename T>
shared_ptr<T> Singleton<T>::_instance;

template<typename T>
mutex Singleton<T>::_mutex;


/*声明单例模式类的类型,使:指针和单例类成为友元类*/
#define DECLARE_SINGLETON_CLASS(type) \
 friend class shared_ptr< type >  ; \
 friend class Singleton< type > ;

#endif 

下面是一个使用示例:Service.h文件

#ifndef SERVICEMANGER_H
#define SERVICEMANGER_H
#include "singleton.h"
#include <iostream>

class ServiceManger
{
 DECLARE_SINGLETON_CLASS(ServiceManger);
public:
 void Run()
 {
  std::cout << "我是张飞,搞单例模式两个晚上" << std::endl; 
 }
 //注意,不能声明为私有,否则报错
 ServiceManger(void);
 ~ServiceManger(void);
};

typedef Singleton<ServiceManger> SSManger;
#endif

Service.cpp

 

#include "ServiceManger.h"


ServiceManger::ServiceManger(void)
{
}


ServiceManger::~ServiceManger(void)
{
}

main.cpp文件

#include <iostream>
#include "ServiceManger.h"

using namespace std;

int main(int argc,char* argv[])
{
 SSManger::instance()->Run();
 getchar();
 return 0;
}

抱歉!评论已关闭.