信息发布→ 登录 注册 退出

C++如何实现单例模式_C++线程安全的单例模式写法

发布时间:2025-11-29

点击量:
单例模式通过私有构造函数、静态实例和公有获取方法确保类唯一实例。基础版本非线程安全,多线程下可能重复创建。使用双检锁加互斥量可实现线程安全,仅首次加锁提升性能,需两次判空防止竞态。C++11起推荐局部静态变量法,编译器保证初始化线程安全,代码简洁无需手动管理锁与内存。该方法自动处理析构,禁用拷贝赋值避免复制。若需延迟初始化可用双检锁配合指针,否则优先局部静态变量。注意构造函数中避免调用其他单例防循环依赖,旧环境需验证C++11支持。现代C++首选局部静态变量实现单例。

c++如何实现单例模式_c++线程安全的单例模式写法

单例模式确保一个类只有一个实例,并提供全局访问点。在C++中,尤其是在多线程环境下,实现线程安全的单例模式需要特别注意构造时机和并发控制。

基本单例模式结构

单例的核心是私有构造函数、静态实例指针和公有的获取实例方法。

一个最基础的版本如下:

// 非线程安全的基础单例 class Singleton { private: static Singleton* instance; Singleton() {} // 私有构造函数

public: static Singleton* getInstance() { if (instance == nullptr) { instance = new Singleton(); } return instance; } };

// 静态成员定义 Singleton* Singleton::instance = nullptr;

这个版本在单线程下可用,但在多线程环境中,多个线程可能同时进入 if 判断,导致多次创建实例。

加锁实现线程安全(双检锁)

使用互斥锁配合双重检查锁定(Double-Checked Locking)可以避免每次调用都加锁,提高性能。

#include

class Singleton { private: static Singleton* instance; static std::mutex mtx; Singleton() {}

public: static Singleton* getInstance() { if (instance == nullptr) { // 第一次检查 std::lock_guard<:mutex> lock(mtx); if (instance == nullptr) { // 第二次检查 instance = new Singleton(); } } return instance; } };

// 静态成员定义 Singleton* Singleton::instance = nullptr; std::mutex Singleton::mtx;

这种写法减少了锁的竞争,只有在第一次创建时才加锁。注意必须进行两次判空,否则仍可能重复创建。

N世界 N世界

一分钟搭建会展元宇宙

N世界 138 查看详情 N世界

C++11后的局部静态变量法(推荐)

C++11标准保证了局部静态变量的初始化是线程安全的,且只执行一次。这是目前最简洁、安全且高效的写法。

class Singleton { private: Singleton() {}

public: static Singleton& getInstance() { static Singleton instance; // 局部静态变量 return instance; }

// 禁用拷贝和赋值
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;

};

这种方式由编译器自动处理线程安全和析构,无需手动管理锁或指针。适用于大多数现代C++项目。

注意事项与建议

  • 如果需要延迟初始化,双检锁+指针方式更合适;否则优先使用局部静态变量。
  • 手动管理内存时,需考虑析构问题,可配合 std::unique_ptr 自动释放。
  • 避免在构造函数中调用其他可能触发单例的函数,防止循环依赖。
  • 某些嵌入式或旧编译器环境可能不完全支持C++11的静态初始化规则,需验证。

基本上就这些。现代C++推荐使用局部静态变量实现单例,代码简洁又安全。

以上就是C++如何实现单例模式_C++线程安全的单例模式写法的详细内容,更多请关注其它相关文章!


相关文章: 没有大陆身份证/银行卡如何实名微信? 亲测有效的几种方法分享  sublime如何优雅地处理行尾空格_sublime自动清理多余空白字符配置  Spyder启动失败:字体文件权限拒绝错误解决方案  12306选座怎么选到商务座_12306商务座选择与配置说明  抖音网页版平台入口 抖音网页版官网在线访问教程  照顾宝贝2小游戏免费秒玩入口  《燕云十六声》两周内达九百万玩家!位居畅销榜第五  微信群消息显示延迟如何解决 微信群消息刷新优化方法  2306选座时如何选靠窗位置_12306选座靠窗座位查看方法解析  Selenium Python中处理点击后新窗口加载冻结问题的策略与实践  Lar*el Migration:重命名列后添加新列的正确操作顺序  MAC怎么安装Homebrew包管理器_MAC为开发者和高级用户安装命令行工具  优化Lar*el Docker镜像:Composer与PHP版本控制策略  如何使用J*aScript精确选择并批量修改特定父元素下子链接的样式  漫蛙网页登录入口 漫蛙漫画官方授权网址  淘宝支付提示失败如何解决 淘宝支付流程优化方法  特斯拉自动驾驶房车计划曝光 原型车将于2027年亮相  Yandex搜索引擎官网入口_俄罗斯Yandex免登录一键直达  构建轻量级网站内部消息系统:Formspree 集成指南  J*aScript中赋值与自增运算符的复杂交互与执行机制  夸克浏览器网页版最新地址 夸克浏览器官方入口合集  移动端XML文件怎么转换成Excel 手机和平板上的解决方案  Lar*el头像管理:图片缩放与旧文件删除的最佳实践  C#如何安全地从用户上传的XML文件中读取数据? 验证与清理策略  虫虫漫画精品漫画官网_虫虫漫画精品漫画官网进入精品漫画  响应式CSS Grid布局:优化网格项在小屏幕下的堆叠与宽度适配  AI泡沫首次被“刺破”:GPU十年都无法存活!  怎么在mac上运行html代码_mac运行html代码方法【指南】  KFC早餐时段怎么领特惠代码_KFC早餐订餐优惠代码获取与使用说明  Lar*el DB::listen 事件中的查询执行时间单位解析  怎样更改Windows系统的默认安装路径_避免C盘爆满的终极设置【技巧】  学习通网页版官方登录 超星学习通电脑端入口指南  Win11怎么查看电脑配置_Win11硬件配置检测工具使用  4399免费游戏网址入口 4399小游戏免费入口点开即玩  高德地图公交到站提醒失败如何解决 高德提醒权限设置  Python中如何避免重复条件判断:利用数据结构实现动态逻辑  如何在低配置电脑上搭建轻量级J*a环境_占用更小的环境选择技巧  谷歌google账号怎么注册账号 谷歌账号注册官方流程  PHP面向对象编程中避免重复创建PDO数据库连接的最佳实践  在Runstone环境中高效处理TasteDive API的JSON数据  C++如何实现一个装饰器模式_C++设计模式之动态地给对象添加额外职责  12306选座怎么选到特殊座位_12306特殊座位选择注意事项  基于动态规划的房屋花卉种植最小成本算法详解  Yandex免登录网页版地址 Yandex搜索引擎官方访问入口  qq音乐在线播放入口_qq音乐电脑版登录链接  在哪找SublimeJ远程工具_SFTP插件配置教程  poki免费入口快捷访问 poki人气小游戏直接玩站点  解决Python单元测试中Mock异常方法调用计数为零的问题  不会效仿卡普空!《铁拳》制作人澄清:不采取赛事付费|直播|  J*a 递归快速排序中静态变量的状态管理与陷阱 

在线客服
服务热线

服务热线

4008988990

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!