详解 Qt 中实现单例模式

移动开发
本文介绍的是Qt 中实现单例模式,由于单例模式很常用,Boost库中有强大的泛型单例实现,先来看内容。

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

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

QMutex SingleTon::mutex;QAtomicPointer<SingleTon> 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:

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

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

责任编辑:zhaolei 来源: 互联网
相关推荐

2013-03-26 10:35:47

Objective-C单例实现

2010-02-05 17:00:06

C++单例模式

2021-07-27 07:31:16

单例模式关键字

2024-03-06 13:19:19

工厂模式Python函数

2021-03-02 08:50:31

设计单例模式

2021-02-01 10:01:58

设计模式 Java单例模式

2022-09-29 08:39:37

架构

2013-11-26 16:20:26

Android设计模式

2016-03-28 10:23:11

Android设计单例

2022-08-10 11:02:56

Python单例模式

2010-02-03 09:43:16

C++单例模式

2011-06-28 15:01:01

Qt PIMPL

2021-09-07 10:44:35

异步单例模式

2022-06-07 08:55:04

Golang单例模式语言

2021-02-07 23:58:10

单例模式对象

2011-03-16 10:13:31

java单例模式

2022-02-06 22:30:36

前端设计模式

2023-12-05 08:20:05

单例模式Python

2024-02-04 12:04:17

2010-02-06 13:42:36

C++单件模式
点赞
收藏

51CTO技术栈公众号