QT的单例模式

18 篇文章 0 订阅
3 篇文章 0 订阅

1、什么是单例模式

单例模式(Singleton Pattern)是一种设计模式,用于确保一个类只有一个实例,并提供全局访问点以访问该实例。这意味着在应用程序的整个生命周期内,只能创建一个特定类的对象。单例模式常用于需要共享资源或控制共享某些资源的情况,以确保资源的一致性和有效管理。

单例模式通常包括以下要素:

  1. 私有构造函数:单例类通常将其构造函数设为私有,以防止外部代码直接实例化类的对象。

  2. 静态成员变量:单例类通常包含一个私有的静态成员变量,用于存储类的唯一实例。

  3. 静态成员函数:单例类通常包含一个公共的静态成员函数,通常命名为 getInstance() 或类似的名称,用于获取单例类的实例。

  4. 延迟初始化:在首次调用 getInstance() 方法时才创建类的唯一实例,以延迟初始化。

  5. 线程安全性:如果在多线程环境中使用单例模式,需要确保线程安全性,以防止多个线程同时创建实例。通常可以使用互斥锁等机制来实现线程安全性。

单例模式的优点包括:

  • 提供全局访问点,方便在应用程序的不同部分共享对象。
  • 确保只有一个实例存在,节省资源。
  • 提供对单一资源或配置的集中管理。
  • 支持懒加载,只在需要时创建实例。

然而,单例模式也有一些缺点,包括:

  • 可能导致全局状态,增加了代码的耦合性。
  • 在某些情况下可能会引入单点故障。
  • 难以进行单元测试,因为单例对象难以模拟或替代。

important:

强调一点在实际写代码中的应用,一般的情况下,qt是用来写界面的,也就是数据源--->显示层,怎么把发送过来的数据做显示,你写代码就是写逻辑。

目前,我看到两种写法,一种是把数据源当作单例写,一种是我自己摸索出来将界面当作单例写,

一般我的处理方法是:

选一个界面作为主界面,所有其他的窗口界面都new在主界面,数据源也new在主界面,写一个单例。

所有界面与界面之间的功能,都可以走主界面的信号与槽,槽函数可以写在自己的界面,这样所有的界面都只用new一次,第一级窗口,第二级窗口,以及第三级窗口,层次就很清楚。

如果一个信号源涉及多个窗口的显示,可以单独开一个类,不至于主界面存在过多的代码了。

2、什么时候使用单例模式

在qt中一般很少会使用单例模式,但是有一种情况,就是你的界面同时接收多个数据源来做显示。

比如,udp给你发数据显示,excel给你发数据显示,MySQL也给你发数据显示,你的这个界面new在了一个主界面中,你想发数据,会造成一种情况就是你自己new出来多个显示界面,这个显示界面却无法显示所有的数据源。

很多人会直接在主界面来处理数据,将所有界面都new在主界面中,这样虽然能够解决问题,但是会造成逻辑代码十分不清晰,主界面的代码量过多。

所以提倡用单例模式。

3、如何使用单例模式

3.1单例的类代码:

.h文件

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QWidget>
#include <QString>

class MyWidget : public QWidget {
    Q_OBJECT
public:
    static MyWidget* getInstance();
    void updateData(const QString& data);

private:
    MyWidget(QWidget* parent = nullptr);
    static MyWidget* instance;
};

#endif // MYWIDGET_H

.cpp文件

#include "MyWidget.h"
#include <QTableWidget> // 如果需要的话,包含其他必要的头文件

MyWidget* MyWidget::instance = nullptr;

MyWidget* MyWidget::getInstance() {
    if (!instance) {
        instance = new MyWidget();
    }
    return instance;
}

MyWidget::MyWidget(QWidget* parent) : QWidget(parent) {
    // 初始化界面部件
}

void MyWidget::updateData(const QString& data) {
    // 更新界面显示
    // 例如,将数据添加到QTableWidget或QListView
}

3.2 如何使用单例的类成员以及函数

包含MyWidget.h头文件,就可以在其他文件中使用MyWidget类

#include "MyWidget.h"

// 在其他地方使用 MyWidget 类
MyWidget* myWidget = MyWidget::getInstance();
myWidget->updateData("Some data to display");

4、对于类中的成员以及函数被其他类多次调用(不属于单例)

在Qt中,如果您有一个类的成员函数或成员变量需要在多个其他类中被调用或使用,可以考虑以下几种方法来组织代码和确保良好的代码复用:

  1. 将该类的对象作为成员变量添加到其他类中:如果多个类需要访问同一个类的成员函数或成员变量,您可以将该类的对象作为其他类的成员变量添加到这些类中。这样,它们就可以通过对象来访问该类的功能。
class ClassA {
public:
    void someFunction() {
        // 调用 ClassB 的成员函数
        classBObject.someFunctionB();
    }

private:
    ClassB classBObject;
};

2、使用继承:如果多个类需要共享某些公共功能,您可以使用继承来实现代码复用。将共享的功能放在基类中,然后其他类可以从该基类继承。

class BaseClass {
public:
    virtual void commonFunction() {
        // 共享的功能实现
    }
};

class DerivedClassA : public BaseClass {
    // 可以重写基类的 commonFunction 或者使用它
};

class DerivedClassB : public BaseClass {
    // 可以重写基类的 commonFunction 或者使用它
};

使用组合:将需要共享的功能封装到一个独立的类中,然后将该类的对象组合到其他类中。这种方式可以实现代码的分离和模块化。

class SharedFunctionality {
public:
    void commonFunction() {
        // 共享的功能实现
    }
};

class ClassA {
public:
    void someFunction() {
        sharedFunctionalityObject.commonFunction();
    }

private:
    SharedFunctionality sharedFunctionalityObject;
};

使用静态成员函数:如果某个功能不需要维护状态并且可以独立于类的实例,您可以将它们声明为静态成员函数,并通过类名直接调用它们。

class ClassA {
public:
    void someFunction() {
        // 调用 ClassB 的静态成员函数
        ClassB::staticFunction();
    }
};

class ClassB {
public:
    static void staticFunction() {
        // 共享的功能实现
    }
};

5、使用静态的成员以及函数

通过类名直接调用静态成员函数:您可以使用该类的名称来直接调用其静态成员函数,而无需创建该类的对象。

// 在类 A 的静态成员函数中定义了某个功能
class ClassA {
public:
    static void staticFunctionA() {
        // 静态成员函数的实现
    }
};

// 在其他类中调用 ClassA 的静态成员函数
ClassA::staticFunctionA();

通过类名访问静态成员变量:同样,您可以使用该类的名称来访问其静态成员变量

// 在类 A 中定义了一个静态成员变量
class ClassA {
public:
    static int staticVariableA;
};

// 在其他类中访问 ClassA 的静态成员变量
int value = ClassA::staticVariableA;

在其他类中包含该类的头文件:如果需要在其他类中使用另一个类的静态成员函数或静态成员变量,确保在其他类的源文件中包含该类的头文件。

// 其他类的源文件中包含 ClassA 的头文件
#include "ClassA.h"

// 然后可以使用 ClassA 的静态成员函数或静态成员变量
ClassA::staticFunctionA();
int value = ClassA::staticVariableA;

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值