Qt实用技巧:设计模式之单例模式,唯一实例类通用模板

简介: Qt实用技巧:设计模式之单例模式,唯一实例类通用模板

若该文为原创文章,转载请注明原文出处

本文章博客地址:https://blog.csdn.net/qq21497936/article/details/80046081

各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究

红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…(点击传送门)

Qt开发专栏:实用技巧(点击传送门)

 

需求

       Qt常需要一个类,全局调用,是设计模式中的单例模式。

 

单例模式

       单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例。

       显然单例模式的要点有三个;

  • 一是某个类只能有一个实例;
  • 二是它必须自行创建这个实例;
  • 三是它必须自行向整个系统提供这个实例。

 

Qt单例模式示例模板(此版本重大bug)

使用DbService::instance()全局获取该对象

头文件

#ifndef DBSERVICE_H
#define DBSERVICE_H
#include <QObject>
#include <QMutex>
#include <QMutexLocker>
class DbService : public QObject
{
    Q_OBJECT
public:
    explicit DbService(QObject *parent = 0);
public:
    static DbService * instance();
signals:
public slots:
protected:
private:
    static DbService *_pInstance;
    static QMutex _mutex;
};
#endif // DBSERVICE_H

源文件(存在bug)

#include "DbService.h"
DbService * DbService::_pInstance = 0;
QMutex DbService::_mutex;
DbService::DbService(QObject *parent) : QObject(parent)
{
}
DbService * DbService::instance()
{
    if(!_pInstance)
    {
        QMutexLocker lock(&_mutex);
        if(!_pInstance)
        {
            _pInstance = new DbService();
        }
    }
    return _pInstance;
}

bug(感谢网友大神:火龙 的帮助)

 

_pInstance = new DbService();

1. 申请DbService的内存

2. 在申请的内存上构造DbService

3. 将_pInstance指针指向这个内存

这个new有这么三步

编译器可能是132这么执行的,多个线程第一次同时使用时,可能出现野指针,即编译器先指向内存(准备第三步构造)时,另一个线程获取,则出现野指针,运行出现段错误。

源文件(修复完bug)

#include "DbService.h"
DbService * DbService::_pInstance = 0;
QMutex DbService::_mutex;
DbService::DbService(QObject *parent) : QObject(parent)
{
}
DbService * DbService::instance()
{
    if(!_pInstance)
    {
        QMutexLocker lock(&_mutex);
        if(!_pInstance)
        {
            DbService *pInstance = new DbService();  // 修改处
            _pInstance = pInstance;                 // 修改处
        }
    }
    return _pInstance;
}

 

Qt单例模式示例模板(修复bug后的单例模式代码2:使用原子caozuo)

 

头文件

#ifndef DBSERVICE_H
#define DBSERVICE_H
#include <QObject>
#include <QMutex>
#include <QMutexLocker>
class DbService : public QObject
{
    Q_OBJECT
public:
    explicit DbService(QObject *parent = 0);
public:
    static DbService *getInstance();
signals:
public slots:
protected:
private:
    static QAtomicPointer<DbService> _instance;
    static QMutex _mutex;
};
#endif // DBSERVICE_H

源文件

#include "DbService.h"
QAtomicPointer<DbService> DbService::_instance = 0;
QMutex DbService::_mutex;
DbService::DbService(QObject *parent) : QObject(parent)
{
}
DbService * DbService::instance()
{
#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 DbService);//第二次检测。
    }
    return _instance;
}

 

本文章博客地址:https://blog.csdn.net/qq21497936/article/details/80046081


相关文章
|
29天前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
27 2
|
10天前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
|
19天前
|
设计模式 存储 数据库连接
PHP中的设计模式:单例模式的深入理解与应用
【10月更文挑战第22天】 在软件开发中,设计模式是解决特定问题的通用解决方案。本文将通过通俗易懂的语言和实例,深入探讨PHP中单例模式的概念、实现方法及其在实际开发中的应用,帮助读者更好地理解和运用这一重要的设计模式。
14 1
|
24天前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
24 0
|
27天前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
本教程详细讲解了Kotlin中的单例模式实现,包括饿汉式、懒汉式、双重检查锁、静态内部类及枚举类等方法,适合需要深入了解Kotlin单例模式的开发者。快速学习者可参考“简洁”系列教程。
27 0
|
27天前
|
设计模式 存储 数据库连接
Python编程中的设计模式之美:单例模式的妙用与实现###
本文将深入浅出地探讨Python编程中的一种重要设计模式——单例模式。通过生动的比喻、清晰的逻辑和实用的代码示例,让读者轻松理解单例模式的核心概念、应用场景及如何在Python中高效实现。无论是初学者还是有经验的开发者,都能从中获得启发,提升对设计模式的理解和应用能力。 ###
|
30天前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
|
15天前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
2月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
17天前
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###

推荐镜像

更多