新闻中心

C++如何实现单例设计模式?C++最常用的设计模式讲解【架构入门】

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

c++如何实现单例设计模式?c++最常用的设计模式讲解【架构入门】

单例模式在C++中核心目标是:确保一个类只有一个实例,并提供全局访问点。它不难写,但容易写错——尤其在多线程、析构顺序和懒加载场景下。

最安全的现代C++写法(C++11起推荐)

利用局部静态变量的“首次调用时初始化”和线程安全特性,代码简洁且天然线程安全:

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 build20230614 S-CMS企业建站系统(含APP/小程序)5.0 build20250614

闪灵CMS企业建站系统是淄博闪灵网络科技有限公司开发的一款专门为企业建站提供解决方案的产品,前端模板样式主打HTML5模板,以动画效果好、页面流畅、响应式布局为特色,程序主体采用PHP+MYSQL构架,拥有独立自主开发的一整套函数、标签系统,具有极强的可扩展性,设计师可以非常简单的开发出漂亮实用的模板。系统自2015年发布第一个版本以来,至今已积累上万用户群,为上万企业提供最优质的建站方案。

S-CMS企业建站系统(含APP/小程序)5.0 build20230614 0 查看详情 S-CMS企业建站系统(含APP/小程序)5.0 build20230614

常见误写与陷阱

  • 手写 double-checked locking(DCLP)不用 memory_order:C++11前易出错,现在应优先用 std::call_once 或静态局部变量
  • 用 new 分配但忘了 delete:导致内存泄漏;建议统一用 std::unique_ptr 管理
  • 把 getInstance 声明为 const 成员函数:错误!获取实例本身是可变操作(首次构造会修改状态)
  • 在构造函数里调用 getInstance:引发死锁或未定义行为(递归初始化静态变量)

什么情况下不该用单例?

单例不是万能解药。以下情况建议绕开:

  • 只是想共享数据 → 用普通全局变量或命名空间内静态对象更轻量
  • 需要多种配置的多个实例(如多个数据库连接)→ 改用工厂 + 对象池
  • 测试困难(全局状态干扰单元测试)→ 考虑依赖注入(传入接口引用)
  • 模块间强耦合 → 单例会隐式引入依赖,破坏可维护性

基本上就这些。单例本身不复杂,但用得是否恰当,往往暴露架构思考深度。

以上就是C++如何实现单例设计模式?C++最常用的设计模式讲解【架构入门】的详细内容,更多请关注其它相关文章!


# ai  # 死锁  # 多个  # 最常用  # 首次  # 建站系统  # 如何实现  # 多线程  # 递归  # 无锁  # c++  # 懒加载  # 加载  # 虹口网站优化选哪家  # 小程序先做网站再做推广  # 泽州关键词排名软件下载  # seo数据实战  # seo 挂机  # 名字营销推广怎么做的  # 安阳县网站建设  # 常州seo排名收费多少  # 菲律宾马卡提seo学徒  # 政务服务网站推广方案  # 全局变量 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: 红果短剧网页版官网入口 官方最新网址发布  蛙漫官网漫画入口地址_蛙漫在线畅读无广告弹窗  Win10磁盘清理工具在哪 Win10打开并使用磁盘清理【教程】  必由学官方登录入口 必由学教师学生账号快速访问  Win11网速慢怎么解决 Win11网络设置优化解除限速  b站怎么取消点赞_b站点赞取消操作方法  cad怎么合并重叠的线段_cad清理重复重叠线条的操作方法  Composer的 "licenses" 命令如何帮助你遵守开源协议_检查项目依赖的许可证合规性  如何将HTML表格多行数据保存到Google Sheet  J*aScript教程:根据元素文本内容动态设置背景色  AO3官方在线访问地址 Archive of Our Own最新镜像合集  俄罗斯Yandex免登录入口_Yandex搜索引擎官网一键直达  2025-2030年全球乘用车销量预测:新能源成增长主力  Win10自动更新怎么关闭 Win10永久关闭系统更新的两种方法【终极版】  ArchiveofOurOwn小说阅读-ArchiveofOurOwn同人作品访问链接  处理动态列数据:J*a ArrayList的正确初始化与字符累加教程  c++中的std::basic_string的SSO优化_c++短字符串优化深度解析  uc浏览器网页版极速入口 uc网页浏览器网页版流畅体验  理解J*aScript Promise的微任务队列与执行顺序  狙击外星人小游戏开始_狙击外星人小游戏立即开始  响应式CSS Grid布局:优化网格项在小屏幕下的堆叠与宽度适配  如何在网页中实现特定地点的随机图片展示  抖音创作助手登录入口_抖音创作辅助工具官网直达  为什么我的微信朋友圈看不到别人的更新_微信朋友圈更新显示异常解决方法  必由学官网首页入口 必由学教师网页版登录指南  Windows7怎么硬盘安装 Windows7提取ISO镜像到非系统盘并运行setup.exe实现硬盘直装【教程】  Mac怎么使用表情符号_Mac Emoji快捷键面板  C++如何实现异步操作_C++11使用std::future和std::async进行异步编程  漫蛙2正版漫画站 漫蛙2网页版快速访问入口  Win11怎么查看电脑配置_Win11硬件配置检测工具使用  腾讯QQ邮箱官方网站_QQ邮箱网页版在线登录  J*aScript动态修改指定div内所有a标签样式指南  Log4j Console Appender性能瓶颈与高并发优化策略  漫蛙官网正版漫画入口 漫蛙2官方网页登录地址  小米Civi 4录制视频过暗_小米Civi 4亮度优化  天眼查怎么看公司融资情况 天眼查企业融资历史查询步骤【攻略】  整合Supabase认证与Django模型:跨模式迁移的解决方案  微信商城在哪里打开【步骤】  如何优雅地解决Livewire文件上传难题?SpatieLivewireFilepond让一切变得简单  Go语言HTML解析:利用Goquery精准获取指定元素内容  必由学网页版入口 必由学官方平台直接访问  Go语言中JSON数据解码与字段访问指南  mysql如何设置表访问权限_mysql表访问权限配置  HTML5原生日期选择器与jQuery UI:实现日期选择器的联动与程序化控制  win11专注助手在哪 Win11免打扰模式设置与自动化规则【指南】  Selenium Python中处理点击后新窗口加载冻结问题的策略与实践  Go调试环境为何无法启动_Go调试器启动失败原因与解决策略  拼多多赚钱渠道_拼多多收益来源  4399体育竞技小游戏_4399小游戏赛事入口  C++如何使用AddressSanitizer(ASan)_C++调试工具中检测内存访问错误的利器 

搜索