C++单例模式最安全写法是C++11起用局部静态变量实现,线程安全且自动管理生命周期;带参数时推荐静态局部变量+工厂函数,避免双重检查锁定陷阱;非必要场景应优先考虑依赖注入或全局对象。

单例模式在C++中核心目标是:确保一个类只有一个实例,并提供全局访问点。它不难写,但容易写错——尤其在多线程、析构顺序和懒加载场景下。
利用局部静态变量的“首次调用时初始化”和线程安全特性,代码简洁且天然线程安全:
class Singleton {
public:
static Singleton& getInstance() {
static Singleton instance; // C++11保证:首次调用时构造,且线程安全
return instance;
}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
private:
Singleton() = default; // 私有构造,禁止外部创建
~Singleton() = default; // 析构可公开或私有,按需决定
};
✅ 优点:无锁、无内存泄漏风险、自动管理生命周期、符合RAII;
❌ 注意:析构时机由程序结束时静态对象销毁顺序决定,若其他静态对象依赖它,可能出问题(称为“静态初始化顺序惨案”)。
如果构造函数需要参数(比如配置路径、日志级别),不能直接用静态局部变量。常用方案是“双重检查锁定 + 智能指针”:
#include <memory>
#include <mutex>
class ConfigurableSingleton {
public:
static ConfigurableSingleton& getInstance(const std::string& configPath) {
// 第一次检查(无锁,快速返回)
if (instance_ != nullptr) {
return *instance_;
}
std::lock_guard<std::mutex> lock(mutex_);
// 第二次检查(加锁后再次确认)
if (instance_ == nullptr) {
instance_ = std::make_unique<ConfigurableSingleton>(configPath);
}
return *instance_;
}
static void destroy() {
std::lock_guard<std::mutex> lock(mutex_);
instance_.reset();
}
private:
explicit ConfigurableSingleton(const std::string& path) {
// 加载配置等耗时操作
}
ConfigurableSingleton(const ConfigurableSingleton&) = delete;
ConfigurableSingleton& operator=(const ConfigurableSingleton&) = delete;
static std::unique_ptr<ConfigurableSingleton> instance_;
static std::mutex mutex_;
};
// 定义静态成员
std::unique_ptr<ConfigurableSingleton> ConfigurableSingleton::instance_;
std::mutex ConfigurableSingleton::mutex_;
⚠️ 注意:必须手动调用 destroy() 避免程序退出前未释放资源;若不想手动管理,可改用静态局部变量+工厂函数封装参数(更推荐)。
S-CMS企业建站系统(含APP/小程序)5.0 build20250614
闪灵CMS企业建站系统是淄博闪灵网络科技有限公司开发的一款专门为企业建站提供解决方案的产品,前端模板样式主打HTML5模板,以动画效果好、页面流畅、响应式布局为特色,程序主体采用PHP+MYSQL构架,拥有独立自主开发的一整套函数、标签系统,具有极强的可扩展性,设计师可以
非常简单的开发出漂亮实用的模板。系统自2015年发布第一个版本以来,至今已积累上万用户群,为上万企业提供最优质的建站方案。
0
查看详情
std::call_once 或静态局部变量std::unique_ptr 管理单例不是万能解药。以下情况建议绕开:
基本上就这些。单例本身不复杂,但用得是否恰当,往往暴露架构思考深度。
以上就是C++如何实现单例设计模式?C++最常用的设计模式讲解【架构入门】的详细内容,更多请关注其它相关文章!
相关文章:
PHP中获取MongoDB服务器运行时间(Uptime)的专业指南
C++的std::mdspan是什么_C++23中用于操作多维数组的非拥有视图
Win11输入法不见了怎么办_Windows11恢复语言栏显示方法
星露谷物语官网入口 星露谷物语游戏官网入口
sublime怎么预览Markdown渲染效果_Markdown Preview插件 for sublime教程
QQ邮箱在线登录平台 QQ邮箱个人邮箱网页版入口
将HTML动态表格多行数据保存到Google Sheet的教程
composer的"require-dev"部分是用来做什么的?
腾讯视频怎么使用多账号家庭管理_腾讯视频家庭多账号统一管理与权限分配教程
C++20的source_location是什么_C++在编译期获取源码位置信息用于日志和断言
Python Socket多播通信中指定源IP地址的实践指南
CSS条件样式无法按设备触发怎么排查_media条件语句正确设置解决触发问题
HTML元素状态管理:根据DIV内容动态启用/禁用按钮
HTML空白字符处理机制:渲染、DOM与编码实践
解决macOS上安装pyhdf时‘hdf.h’文件缺失的编译错误
大麦的“候补”是什么意思 大麦候补购票规则【详解】
如何设置Windows Defender的定时扫描_计划任务实现自动杀毒【安全】
Python中高效访问嵌套字典与列表中的键值对
PHP教程:高效从URL路径中提取倒数第二个片段
PHP文件上传至S3:策略、考量与避免本地存储的挑战
2025AO3夸克浏览器通道_AO3手机HTTPS安全入口分享
Log4j Console Appender性能瓶颈与高并发优化策略
AO3最新入口2025公告_AO3中文官网合集
GemBox Document HTML转PDF垂直文本渲染问题及解决方案
海棠账号登录入口_登录海棠账户同步阅读记录
outlook中文官网入口地址 outlook官方中文版直达首页链接
邮编格式怎么匹配地址_根据邮编格式快速匹配详细地址的技巧
Lar*el 8 多关键词数据库搜索优化实践
Centos/Linux 系统下安装 composer 的完整步骤
Lar*el DB::listen 事件中的查询执行时间单位解析
Safari怎么安装扩展程序 浏览器插件安装与管理方法【详解】
魅族20怎样在浏览器开无图省流_iPhone魅族20浏览器开无图省流【流量节省】
拼多多视频播放卡顿如何处理 拼多多视频播放优化技巧
谷歌学术网站直达地址 谷歌学术搜索网页版一键进入
蛙漫2日版入口 WAMAN2(日版)无删减漫画官网链接
PPT平滑切换怎么做 PPT炫酷“平滑”切换动画制作教程【必学】
树莓派传感器触发:通过Twilio API发送WhatsApp消息教程
vivo手机参数配置怎么增强信号_vivo手机参数配置信号增强方法
c++中为什么推荐使用using替代typedef_c++现代化类型别名
Node.js CSV 数据处理:基于字段空值条件过滤整条记录的策略
MAC如何安全彻底地删除文件_MAC使用终端命令确保文件无法被恢复
解决Bootstrap卡片顶部边距导致背景图下移的问题
Highcharts 雷达图径向轴标签定制指南:利用多Y轴实现数值标注
qq音乐在线播放入口_qq音乐电脑版登录链接
MongoDB Aggregation:在嵌套对象数组中精确匹配ObjectId
Win11 USB传输速度慢怎么解决 Win11 USB驱动更新与设置
在Go开发中优雅管理ListenAndServe进程:GoSublime集成方案
微博网页版官方账号登录 微博网页版内容浏览使用指南
Mac怎么锁定备忘录_Mac备忘录加密设置教程
淘宝支付提示失败如何解决 淘宝支付流程优化方法