Qt 中单例模式的超通俗理解
·
一、什么是单例?
单例 = 整个程序里,这个类永远只有 1 个对象,永远不会创建第二个。
就像:
- 一个公司只有 1 个老板
- 一个程序只有 1 个配置管理
- 一个软件只有 1 个日志管理器
- 一个项目只有 1 个数据库连接
你不管在哪里调用,拿到的都是同一个实例。
二、为什么要用单例?(Qt 里最常见场景)
在 Qt 开发中,单例几乎必用,原因:
- 全局共享数据(配置、用户信息、主题、日志)
- 避免重复创建资源(数据库、网络、串口、文件)
- 全局统一调用(任何页面都能直接用,不用传对象)
- 防止多份实例导致数据错乱、冲突
三、单例的核心特点(记住这 4 点就够)
- 构造函数私有化 → 不让外面随便 new
- 提供一个静态获取实例的方法(如
instance()) - 全局唯一 → 永远只有一个对象
- 线程安全可选(Qt 常用)
四、Qt 中最标准、最常用的单例写法(直接复制用)
这是工业级写法,线程安全 + 懒加载 + 无法外部创建。
1. 头文件 (.h)
cpp
运行
#ifndef CONFIGMANAGER_H
#define CONFIGMANAGER_H
#include <QObject>
class ConfigManager : public QObject
{
Q_OBJECT
public:
// 唯一获取实例的接口(全局只有这一个对象)
static ConfigManager& instance();
// 示例:你可以加自己的函数/变量
void setValue(const QString& key, const QVariant& value);
QVariant getValue(const QString& key);
private:
// 私有化构造!重点!外部不能 new
explicit ConfigManager(QObject *parent = nullptr);
// C++ 禁止拷贝和赋值(保证单例不被复制)
ConfigManager(const ConfigManager&) = delete;
ConfigManager& operator=(const ConfigManager&) = delete;
private:
// 自己的成员变量
QVariantMap m_configData;
};
#endif // CONFIGMANAGER_H
2. 源文件 (.cpp)
cpp
运行
#include "ConfigManager.h"
// 获取单例实例
ConfigManager& ConfigManager::instance()
{
// static 保证只会创建一次
static ConfigManager s_instance;
return s_instance;
}
// 构造函数私有化
ConfigManager::ConfigManager(QObject *parent)
: QObject(parent)
{
}
// 示例方法
void ConfigManager::setValue(const QString& key, const QVariant& value)
{
m_configData[key] = value;
}
QVariant ConfigManager::getValue(const QString& key)
{
return m_configData.value(key);
}
五、怎么使用?(任何地方都能直接调用)
cpp
运行
// 不需要 new!不需要指针!直接用!
ConfigManager::instance().setValue("ip", "192.168.1.1");
QString ip = ConfigManager::instance().getValue("ip").toString();
不管你在 MainWindow、弹窗、子页面、工具类里调用,拿到的永远是同一个对象。
六、最关键的一句话总结
单例就是:一个类,整个程序只造一个对象,到处共用,不能复制,不能随便新建。
七、Qt 里常见的单例用途
- 配置管理
ConfigManager - 日志管理
LogManager - 数据库管理
DbManager - 串口 / 网络管理
SerialPort - 全局主题 / 样式
ThemeManager - 共享数据传递(替代全局变量)
八、你可能会问的问题
1. 单例和全局变量有什么区别?
- 全局变量:不安全、可被随意修改、没有封装
- 单例:安全、可控、只能通过接口访问、唯一实例
2. 这个写法线程安全吗?
在 C++11 及以上是安全的,Qt 5/6 都满足。
3. 单例可以用在 QML 里吗?
可以!注册到 QML 上下文就能在 QML 里当全局单例用。
总结
- 单例 = 全局唯一实例
- 禁止外部创建、禁止拷贝
- static instance () 是唯一入口
- Qt 开发几乎必用,用于共享资源、全局管理
- 上面的代码直接复制就能用
本人电子信息工程专业,工作逼迫写qt软件,一步一步学习qt,从非软件专业视角学习qt,遇到很多奇葩问题,请关注微信公众号。

更多推荐

所有评论(0)