Qt中实现单例模式(SingleTon)
单例模式分为“饥汉”和“饿汉”两种版本,也正是线程安全问题使得原本简单的单例模式变得复杂。由于单例模式很常用,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。*/
};
欢迎大家拍砖!

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

看看 http://qt-project.org/wiki/Qt_thread-safe_singleton, 有很好的实现。

很久以前的文章了,实际上更Qt化的方法是直接用Q_GLOBAL_STATIC。

Qt中实现单例模式(SingleTon),大约有3种办法的更多相关文章

  1. QT中获取选中的radioButton的两种方法(动态取得控件的objectName之后,对名字进行比较)

    QT中获取选中的radioButton的两种方法   QT中要获取radioButton组中被选中的那个按钮,可以采用两种如下两种办法进行: 方法一:采用对象名称进行获取 代码: 1 QRadioBu ...

  2. [转]MFC子线程中更新控件内容的两种办法

    一.概述 每个系统中都有线程(至少都有一个主线程),而线程最重要的作用就是并行处理,提高软件的并发率.针对界面来说,还能提高界面的响应能力.一般的,为了应用的稳定性,在数据处理等耗时操作会单独在一个线 ...

  3. Qt中(图片)资源的三种使用方式

    Qt中使用图片资源的方法有很多种,以前我一直分不清各种之间的区别和Qt相应的处理机制,后来遇到一些实际的问题,然后再加上查阅源码和资料,总算弄明白一些事情,但是本文仅仅是个人理解,如有错误之处请告诉我 ...

  4. 【Qt开发】qt中涉及到空格包含路径的解决办法

    qt中涉及到空格路径,qmake是无法正确编译的. 需要在空格路径前面加上$$quote INCLUDEPATH += $$quote(C:/Program Files/MySQL/MySQL Ser ...

  5. QT中获取选中的radioButton的两种方法

    QT中要获取radioButton组中被选中的那个按钮,可以采用两种如下两种办法进行: 方法一:采用对象名称进行获取 代码: 1 QRadioButton* pbtn = qobject_cast&l ...

  6. c++中实现单例模式singleton class

    本文首发于个人博客https://kezunlin.me/post/8932eaec/,欢迎阅读! singleton class and usage in c++. Guide what singl ...

  7. Qt中PushButton的pressed,released,clicked三种响应的区别

    Qt的PushButton的常用的三种响应有pressed,released和clicked. 优先级:pressed>released>clicked 按下按钮pressed函数的内容, ...

  8. Swift 实现单例模式Singleton pattern的三种方法

    转自:点击打开链接 From my short experience with Swift there are three approaches to implement the Singleton ...

  9. Qt 中使用Singleton模式需小心

    在qt中,使用Singleton模式时一定要小心.因为Singleton模式中使用的是静态对象,静态对象是直到程序结束才被释放的,然而,一旦把该静态对象纳入了Qt的父子对象体系,就会导致不明确的行为. ...

随机推荐

  1. docker-windows随笔资料整理

    背景 业务需求:优化机器学习,IOT边缘计算性能,替换现有的虚拟机部署方案. 技术背景: .netcore python Docker 学习资料 Docker中文社区: http://www.dock ...

  2. 国产操作系统剽窃Linux内核可耻!

    10月28日,新浪科技发表文章,题为"国产操作系统迎来利好:部委机构正大量採购",读后有感. 如今,国家进入法制时代.政府採购"国产操作系统",似乎成为一种&q ...

  3. 【OC语法要闻速览】一、方法调用

    调用方法 [object method]; [object methodWithInput:input]; output = [object methodWithOutput]; output = [ ...

  4. WPF 获取 ListView DataTemplate 中控件值

    原文:WPF 获取 ListView DataTemplate 中控件值 版权声明:本文为博主原创文章,未经博主允许可以随意转载 https://blog.csdn.net/songqingwei19 ...

  5. 努比亚Z7 mini刷机教程_recovery卡刷机教程

    之前小编分享努比亚Z7 mini电话访问Root权限.recovery刷机教程. 所以对于朋友谁搞机整机的爱,左边是写第三方手机刷包.那么下面刷的家小编与您分享努比亚Z7 mini刷机教程手机. 一. ...

  6. linux C Obstack

    Obstack介绍 Obstack初始化 在Obstack中申请对象 释放对象 申请growing object 获取Obstack状态 数据对齐 以下是来自wiki对obstack的介绍: Obst ...

  7. C++ CGI开发环境备录

    1. 安装apache2: apt-get install apache2 2. 配置用户目录 在/etc/apache2/apache2.conf中配置用户目录 <Directory /hom ...

  8. IOS开发之把 Array 和 Dictionaries 序列化成 JSON 对象

    1 前言通过 NSJSONSerialization 这个类的 dataWithJSONObject:options:error:方法来实现,Array 和 dictionary 序列化成 JSON ...

  9. Win8 Metro(C#)数字图像处理--2.50图像运动模糊

    原文:Win8 Metro(C#)数字图像处理--2.50图像运动模糊  [函数名称] 图像运动模糊算法    MotionblurProcess(WriteableBitmap src,int  ...

  10. MS SQL SERVER搜索某个表的主键所在的列名

    原文:MS SQL SERVER搜索某个表的主键所在的列名 SELECT SYSCOLUMNS.name  FROM SYSCOLUMNS,SYSOBJECTS,SYSINDEXES,SYSINDEX ...