0

0

c++单例模式实现_c++设计模式代码演示

裘德小鎮的故事

裘德小鎮的故事

发布时间:2026-01-02 17:19:02

|

336人浏览过

|

来源于php中文网

原创

std::call_once比双重检查锁更安全,因其由标准库保证“只执行一次”并内置内存序约束,避免竞态;而双重检查锁易因两个线程同时通过判空导致重复构造。

c++单例模式实现_c++设计模式代码演示

为什么 std::call_once 比双重检查锁更安全

直接用 pthread_once 或手写 if (instance == nullptr) 加锁,容易在多线程下触发竞态:两个线程同时通过第一次判空,都进入加锁块,其中一个构造完,另一个又构造一次,导致未定义行为。C++11 起推荐用 std::call_once,它由标准库保证「只执行一次」且带内存序约束。

  • std::call_once 内部使用原子操作 + 系统原语(如 futex),无需手动管理锁对象生命周期
  • 必须搭配 std::once_flag 使用,该 flag 必须是静态或全局生存期,不能放在
  • 构造函数若抛异常,std::call_once 会重试下一次调用 —— 所以务必确保初始化逻辑无异常,或在外层捕获

懒汉式单例的线程安全实现(C++11)

下面是最简、可直接编译的线程安全懒汉式单例。关键点:静态局部变量的初始化在 C++11 中是线程安全的,且只发生一次 —— 这其实是比 std::call_once 更简洁的方案。

class Singleton {
public:
    static Singleton& getInstance() {
        static Singleton instance; // ✅ C++11 guaranteed thread-safe initialization
        return instance;
    }
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;

private: Singleton() = default; // 可在此做资源初始化 ~Singleton() = default; };

注意:static Singleton instance 的构造发生在首次调用 getInstance() 时,且标准强制要求编译器插入必要的同步机制(如 GCC/Clang 生成 __cxa_guard_acquire 等)。不需要额外头文件,不依赖

饿汉式单例的隐式初始化风险

把实例声明为静态成员变量看似简单:

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

响应式黑色展台设计整站模板1.4.2
响应式黑色展台设计整站模板1.4.2

响应式黑色展台设计整站模板,自带内核安装即用,图片文本实现可视化,方便修改,支持多种内容模型及自定义功能,可根据需要自行添加。模板特点: 1、安装即用,自带人人站CMS内核及企业站展示功能(产品,新闻,案例展示等),并可根据需要增加表单 搜索等功能(自带模板) 2、支持响应式 3、前端banner轮播图文本均已进行可视化配置 4、伪静态页面生成 5、支持内容模型、多语言、自定义表单、筛选、多条件搜

下载
class Singleton {
private:
    static Singleton instance; // ❌ 静态成员定义需在 .cpp 中
public:
    static Singleton& getInstance() { return instance; }
};
Singleton Singleton::instance; // 在 .cpp 中定义

但问题在于:这个 instance 的构造时机由翻译单元加载顺序决定,可能早于 main() 执行 —— 若其构造函数依赖其他尚未初始化的全局对象(比如某个日志器、配置管理器),就会触发静态初始化顺序惨案(Static Initialization Order Fiasco)。除非你能 100% 控制所有相关全局对象的定义顺序,否则不建议。

  • 饿汉式无法延迟初始化,哪怕程序从不调用 getInstance(),也会构造
  • 若构造函数含副作用(如打开文件、连接数据库),可能造成资源浪费或启动失败
  • 单元测试中难以重置状态,因为实例在进程生命周期内一直存在

如何支持单例的显式销毁与重置

标准单例通常不提供销毁接口,因为析构时机不可控;但测试或插件热重载场景下,你可能需要「释放+重建」。此时不能靠静态局部变量(它只初始化一次),得退回到 std::call_once + 原始指针方案,并手动管理生命周期:

class Singleton {
public:
    static Singleton& getInstance() {
        std::call_once(initFlag, []{
            instance = new Singleton();
        });
        return *instance;
    }
static void destroy() {
    delete instance;
    instance = nullptr;
}

private: static Singleton instance; static std::once_flag initFlag; Singleton() = default; }; Singleton Singleton::instance = nullptr; std::once_flag Singleton::initFlag;

注意:destroy() 后再次调用 getInstance() 会重新构造,但必须确保没有其他线程正在使用旧实例 —— 这种模式本质上放弃了「自动生命周期管理」,把同步责任交还给调用方。生产代码中慎用,除非明确需要重置语义。

真正难的不是写出来,而是想清楚:这个单例是否真需要跨整个进程生命周期存在?它的初始化是否真的昂贵?有没有可能是过度设计?

相关专题

更多
if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

713

2023.08.22

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

994

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

53

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

238

2025.12.29

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

373

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

563

2023.08.10

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

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

473

2023.08.10

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

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

131

2025.12.24

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

74

2025.12.31

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 0.9万人学习

进程与SOCKET
进程与SOCKET

共6课时 | 0.3万人学习

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

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