详解 Qt 中实现单例模式
创始人
2024-08-01 22:51:23
0

Qt 中实现单例模式是本文要介绍的内容,不多说,先来看内容。单例模式分为“饥汉”和“饿汉”两种版本,也正是线程安全问题使得原本简单的单例模式变得复杂。由于单例模式很常用,Boost库中有强大的泛型单例实现,我也利用Qt的原子指针QAtomicPointer来实现Qt中的单例模式

  1. //.cpp  
  2. class  
  3.  SingleTon{ public  
  4. :    /*! \brief 用于获得SingleTon实例,使用单例模式。  
  5.      *  \return SingleTon实例的引用。  
  6.      */  
  7.     static  
  8.  SingleTon &getInstance(void  
  9. )    {        //使用双重检测。  
  10.          if  
  11. (!instance)//***次检测  
  12.         {            QMutexLocker locker(&mutex);//加互斥锁。  
  13.              if  
  14. (!instance)//第二次检测。  
  15.                 instance = new 
  16.  SingleTon;        }         return  
  17.  *instance;    } private  
  18. :    SingleTon();//禁止构造函数。  
  19.     SingleTon(const  
  20.  SingleTon &);//禁止拷贝构造函数。  
  21.     SingleTon & operator 
  22. =(const  
  23.  SingleTon &);//禁止赋值拷贝函数。  
  24.      QReadWriteLock internalMutex;//函数使用的读写锁。  
  25.      static  
  26.  QMutex mutex;//实例互斥锁。  
  27.     static  
  28.  QAtomicPointer instance;/*!<使用原子指针,默认初始化为0。*/  
  29. };//静态成员变量初始化。(在.cpp文件中) 

QMutex SingleTon::mutex;QAtomicPointer SingleTon::instance = 0;

双重锁检测在C++中是安全的,另外提供了读写锁,在修改单例数据的函数中使用写锁(QWriteLocker locker(&internalMutex););在读取单例数据的函数中使用读锁(QReadLocker locker(&internalMutex);)。
之前没考虑到乱序执行问题,并且此前代码有严重BUG,即对QAtomicPointer类型变量赋值操作不是原子操作,见官方文档:

For convenience, QAtomicPointer provides pointer comparison, cast, dereference, and assignment operators. Note that these operators are not atomic.

修改代码,使用testAndSetOrdered原子操作,并解决乱序执行问题,testAndSetOrdered特性:

This function uses ordered memory ordering semantics, which ensures that memory access before and after the atomic operation (in program order) may not be re-ordered.

其中关于memory ordering,我转过此帖:http://www.cnblogs.com/codingmylife/archive/2010/04/28/1722573.html

其中关于double checked locking,有此文:http://docs.huihoo.com/ace_tao/lifecycle.html

修改版SingleTon.cpp:

  1. //.cpp 一次修改版  
  2. class  
  3.  SingleTon{ public  
  4. :    /*! \brief 用于获得SingleTon实例,使用单例模式。  
  5.      *  \return SingleTon实例的引用。  
  6.      */  
  7.     static  
  8.  SingleTon &getInstance(void  
  9. )    { #ifndef  
  10.  Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE        if  
  11. (!QAtomicPointer::isTestAndSetNative())//运行时检测  
  12.             qDebug() << "Error: TestAndSetNative not supported!"  
  13. ;#endif  
  14.          //使用双重检测。  
  15.          /*! testAndSetOrders操作保证在原子操作前和后的的内存访问  
  16.          * 不会被重新排序。  
  17.          */  
  18.         if  
  19. (instance.testAndSetOrdered(0, 0))//***次检测  
  20.         {            QMutexLocker locker(&mutex);//加互斥锁。  
  21.              instance.testAndSetOrdered(0, new  
  22.  SingleTon);//第二次检测。  
  23.         }         return  
  24.  *instance;    } private  
  25. :    SingleTon();//禁止构造函数。  
  26.     SingleTon(const  
  27.  SingleTon &);//禁止拷贝构造函数。  
  28.     SingleTon & operator 
  29. =(const  
  30.  SingleTon &);//禁止赋值拷贝函数。  
  31.      QReadWriteLock internalMutex;//函数使用的读写锁。  
  32.      static  
  33.  QMutex mutex;//实例互斥锁。  
  34. static  
  35.  QAtomicPointer instance;/*!<使用原子指针,默认初始化为0。*/  
  36. }; 

小结:详解Qt 中实现单例模式的内容介绍完了,希望本文对你有帮助!

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
Windows恶意软件20年“... 在Windows的早期年代,病毒游走于系统之间,偶尔删除文件(但被删除的文件几乎都是可恢复的),并弹...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
着眼MAC地址,解救无法享受D... 在安装了DHCP服务器的局域网环境中,每一台工作站在上网之前,都要先从DHCP服务器那里享受到地址动...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...