0

0

C++如何实现单例模式的饿汉式与懒汉式_C++经典设计模式对比【总结】

裘德小鎮的故事

裘德小鎮的故事

发布时间:2026-02-08 08:48:10

|

887人浏览过

|

来源于php中文网

原创

饿汉式单例在程序启动时即初始化,线程安全但可能浪费资源;懒汉式延迟初始化节省资源,但需用双重检查锁定或std::call_once保障线程安全,且析构和内存泄漏风险更高。

c++如何实现单例模式的饿汉式与懒汉式_c++经典设计模式对比【总结】

饿汉式单例:启动时就构造,线程安全但可能浪费资源

饿汉式在程序加载时就完成实例初始化,天然线程安全,不用加锁。但它的问题是:哪怕你整个程序一次都没调用 getInstance(),构造函数也会执行,如果构造开销大(比如读配置、连数据库),就白耗资源。

实操建议:

  • 把静态成员变量直接定义在类外,或用静态局部变量(C++11 起保证首次调用时初始化且线程安全)
  • 构造函数设为 private,禁止外部 new;拷贝/移动构造和赋值全删掉(= delete)
  • 返回引用比返回指针更常见,避免裸指针生命周期困惑

示例关键片段:

class Singleton {
private:
    Singleton() { /* heavy init */ }
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
public:
    static Singleton& getInstance() {
        static Singleton instance; // C++11 线程安全的局部静态
        return instance;
    }
};

懒汉式单例:第一次调用才创建,需手动处理线程安全

懒汉式延迟初始化,节省资源,但多线程环境下极易出错——两个线程同时判断 instance == nullptr 为真,接着都执行 new,结果构造两次,返回不同对象。

立即学习C++免费学习笔记(深入)”;

常见错误现象:

  • 没加锁,多线程下出现多个实例(getInstance() 返回地址不一致)
  • 只对 new 加锁,但没对判空加锁,仍可能重复构造
  • std::call_once + std::once_flag 是更简洁安全的选择(C++11)

推荐写法(双重检查锁定 DCLP,注意必须用 volatile 或原子指针防重排序,C++11 后推荐用 std::atomic):

class Singleton {
private:
    static std::atomic instance;
    Singleton() = default;
public:
    static Singleton* getInstance() {
        Singleton* ptr = instance.load();
        if (ptr == nullptr) {
            std::lock_guard lock(mutex_);
            ptr = instance.load();
            if (ptr == nullptr) {
                ptr = new Singleton();
                instance.store(ptr);
            }
        }
        return ptr;
    }
};

为什么 C++11 后推荐用局部静态变量写饿汉式

因为标准明确要求:函数内静态局部变量的初始化是线程安全的,且仅发生一次。这比手写锁、std::call_once 更简洁,也比全局静态对象更可控(避免静态初始化顺序问题)。

文赋Ai论文
文赋Ai论文

专业/高质量智能论文AI生成器-在线快速生成论文初稿

下载

使用场景:

  • 初始化不依赖其他全局对象(否则可能因初始化顺序未定义而崩溃)
  • 构造函数不抛异常(否则局部静态初始化失败后再次调用会直接 terminate)
  • 不需要在程序退出时显式析构(静态局部变量析构时机由实现决定,不可控)

参数差异不大,但要注意:局部静态变量的析构函数调用顺序与构造相反,且不保证跨编译单元的顺序——这点常被忽略。

懒汉式析构和内存泄漏风险怎么处理

懒汉式用 new 分配的实例,如果不手动释放,程序退出时不会自动调用析构函数,资源(如文件句柄、内存池)可能没清理。但手动 delete 又引入“何时 delete”的新问题。

实操建议:

  • 避免在懒汉式中管理需要显式清理的资源;优先用 RAII 封装(如智能指针、文件流)
  • 若必须控制析构时机,可用 std::atexit() 注册清理函数,但要确保该函数只执行一次,且不能依赖其他静态对象
  • 更稳妥的做法是:改用饿汉式 + 局部静态变量,靠语言机制保证析构(虽然时机不可控,但至少会发生)

容易踩的坑:用 std::shared_ptr 管理懒汉式实例,却忘了它默认的删除器不调用析构函数——得传自定义删除器,否则照样泄漏。

真正麻烦的不是写法本身,而是单例生命周期和资源清理边界的模糊性。很多人卡在“要不要删”“什么时候删”“删了别人还在用怎么办”,而不是语法细节。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
c++中volatile关键字的作用
c++中volatile关键字的作用

本专题整合了c++中volatile关键字的相关内容,阅读专题下面的文章了解更多详细内容。

69

2025.10.23

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

613

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

283

2025.12.24

java多线程相关教程合集
java多线程相关教程合集

本专题整合了java多线程相关教程,阅读专题下面的文章了解更多详细内容。

21

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

23

2026.01.21

C# 多线程与异步编程
C# 多线程与异步编程

本专题深入讲解 C# 中多线程与异步编程的核心概念与实战技巧,包括线程池管理、Task 类的使用、async/await 异步编程模式、并发控制与线程同步、死锁与竞态条件的解决方案。通过实际项目,帮助开发者掌握 如何在 C# 中构建高并发、低延迟的异步系统,提升应用性能和响应速度。

18

2026.02.06

数据库Delete用法
数据库Delete用法

数据库Delete用法:1、删除单条记录;2、删除多条记录;3、删除所有记录;4、删除特定条件的记录。更多关于数据库Delete的内容,大家可以访问下面的文章。

283

2023.11.13

drop和delete的区别
drop和delete的区别

drop和delete的区别:1、功能与用途;2、操作对象;3、可逆性;4、空间释放;5、执行速度与效率;6、与其他命令的交互;7、影响的持久性;8、语法和执行;9、触发器与约束;10、事务处理。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

217

2023.12.29

Golang处理数据库错误教程合集
Golang处理数据库错误教程合集

本专题整合了Golang数据库错误处理方法、技巧、管理策略相关内容,阅读专题下面的文章了解更多详细内容。

61

2026.02.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号