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. Android 在子线程中更新UI的几种方法

    第一种: new Handler(context.getMainLooper()).post(new Runnable() { @Override public void run() { // 在这里 ...

  2. OpenCV For iOS 1:&#160;连接OpenCV 3.0

    本文的内容參考Instant OpenCV for iOS结合最新的开发平台完毕. 本系列文章採用的的开发环境为: 1)Xcode 6 2)OpenCV for iOS 3.0.0 alpha 接下来 ...

  3. SCJP考试题310-025(第二套<4>)92-147/147

    310-025 Leading the way in IT testing and certification tools,QUESTION NO: 92 Given: 1. String foo = ...

  4. CP_ACP : CP_OEMCP

    // filesystem windows_file_codecvt.cpp -----------------------------------------// // Copyright Bema ...

  5. 机器学习、深度学习实战细节(batch norm、relu、dropout 等的相对顺序)

    cost function,一般得到的是一个 scalar-value,标量值: 执行 SGD 时,是最终的 cost function 获得的 scalar-value,关于模型的参数得到的: 1. ...

  6. redis,docker和kubernetes留言簿案例实战

    kubernetes实战-基于redis和docker的留言簿案例 [置顶] kubernetes实战-基于redis和docker的留言簿案例 标签: dockerkubernetesredis 2 ...

  7. XF警告试图

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  8. WPF 使用字体引发的 CLR20r3 问题排查

    开发机器上运行完好,拷贝置目标机器上出现此问题 问题排查: 计算机-->管理-->事件查看器--->windows日志-->应用程序 Application Error  看不 ...

  9. JS 扩展方法prototype

    通过类对象的prototype设置扩展方法,下面为String对象增加quote(两边加字符)方法 <script type="text/javascript"> St ...

  10. WPF ObjectDataProvider的使用-只能检索用

    <Window x:Class="CollectionBinding.MainWindow"        xmlns="http://schemas.micros ...