Qt中实现单例模式(SingleTon)

转载自:http://www.cnblogs.com/codingmylife/archive/2010/07/14/1777409.html


单例模式分为“饥汉”和“饿汉”两种版本,也正是线程安全问题使得原本简单的单例模式变得复杂。由于单例模式很常用,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。*/
};

//静态成员变量初始化。
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。*/
};



  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
YOLO高分设计资源源码,详情请查看资源内容使用说明 YOLO高分设计资源源码,详情请查看资源内容使用说明 YOLO高分设计资源源码,详情请查看资源内容使用说明 YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值