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


相关文章
|
6天前
|
设计模式 存储 安全
PHP中的设计模式:单例模式深度解析
在软件开发的广袤天地中,设计模式如同璀璨星辰,指引着程序员们解决复杂问题的方向。其中,单例模式以其独特的魅力,确保了一个类仅有一个实例,并提供了一个访问它的全局访问点,成为众多项目中不可或缺的设计智慧。本文旨在深入探讨PHP中单例模式的实现方式、应用场景及背后的哲理,引导读者思考其在现代软件架构中的重要性与运用策略。
20 5
|
11天前
|
设计模式 安全 Java
Java 编程中的设计模式:单例模式的深度解析
【9月更文挑战第22天】在Java的世界里,单例模式就像是一位老练的舞者,轻盈地穿梭在对象创建的舞台上。它确保了一个类仅有一个实例,并提供全局访问点。这不仅仅是代码优雅的体现,更是资源管理的高手。我们将一起探索单例模式的奥秘,从基础实现到高级应用,再到它与现代Java版本的舞蹈,让我们揭开单例模式的面纱,一探究竟。
23 11
|
7天前
|
设计模式 存储 缓存
PHP中的设计模式:单例模式的深入解析
在PHP开发中,设计模式是提高代码可维护性、扩展性和重用性的关键技术之一。本文将深入探讨PHP中的单例模式,包括其定义、实现方式、应用场景以及优缺点。通过对单例模式的全面剖析,帮助开发者更好地理解和应用这一设计模式,从而编写出更加高效和优雅的PHP代码。
|
6天前
|
设计模式 安全 Java
设计模式--单例模式Singleton
这篇文章详细介绍了单例模式Singleton的八种实现方式,包括饿汉式(静态常量和静态代码块)、懒汉式(线程不安全和线程安全的同步方法、同步代码块)、双重检查、静态内部类和枚举。每种方式都有详细的代码示例和优缺点说明,帮助理解单例模式的应用和选择适合的实现方法。
设计模式--单例模式Singleton
|
9天前
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP的编程实践中,设计模式是解决常见软件设计问题的最佳实践。单例模式作为设计模式中的一种,确保一个类只有一个实例,并提供全局访问点,广泛应用于配置管理、日志记录和测试框架等场景。本文将深入探讨单例模式的原理、实现方式及其在PHP中的应用,帮助开发者更好地理解和运用这一设计模式。
在PHP开发中,单例模式通过确保类仅有一个实例并提供一个全局访问点,有效管理和访问共享资源。本文详细介绍了单例模式的概念、PHP实现方式及应用场景,并通过具体代码示例展示如何在PHP中实现单例模式以及如何在实际项目中正确使用它来优化代码结构和性能。
|
7天前
|
设计模式 Java 安全
Java设计模式-单例模式(2)
Java设计模式-单例模式(2)
|
5天前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
19天前
|
设计模式 算法 安全
设计模式——模板模式
模板方法模式、钩子方法、Spring源码AbstractApplicationContext类用到的模板方法
设计模式——模板模式
|
12天前
|
设计模式 数据库连接 PHP
PHP中的设计模式:如何提高代码的可维护性与扩展性在软件开发领域,PHP 是一种广泛使用的服务器端脚本语言。随着项目规模的扩大和复杂性的增加,保持代码的可维护性和可扩展性变得越来越重要。本文将探讨 PHP 中的设计模式,并通过实例展示如何应用这些模式来提高代码质量。
设计模式是经过验证的解决软件设计问题的方法。它们不是具体的代码,而是一种编码和设计经验的总结。在PHP开发中,合理地使用设计模式可以显著提高代码的可维护性、复用性和扩展性。本文将介绍几种常见的设计模式,包括单例模式、工厂模式和观察者模式,并通过具体的例子展示如何在PHP项目中应用这些模式。
|
9天前
|
设计模式 Java Spring
spring源码设计模式分析-代理设计模式(二)
spring源码设计模式分析-代理设计模式(二)
下一篇
无影云桌面