单例模式(Singleton Pattern)

C++ 单例模式

单例模式(Singleton Pattern)

一、核心定义

单例模式是创建型设计模式 ,确保一个类有且只有一个实例,并提供一个全局访问点获取该实例。

二、核心特点

  1. 一个类只能创建唯一对象
  2. 自行创建实例
  3. 向整个系统提供这个实例
  4. 无参构造函数私有化
  5. 禁止拷贝、禁止赋值

三、使用场景

  • 日志管理器
  • 配置文件读取
  • 数据库连接池
  • 线程池、缓存、打印机池
  • 全局唯一的工具类

四、C++ 单例模式 5 种标准实现(可直接编译)

实现 1:饿汉式(最简单、线程安全)

程序启动时就创建实例,天生线程安全,无多线程问题。

cpp 复制代码
#include <iostream>
using namespace std;

class Singleton
{
public:
    // 全局访问点
    static Singleton& getInstance()
    {
        return instance;
    }

    void show()
    {
        cout << "饿汉式单例" << endl;
    }

    // 禁止拷贝、禁止赋值
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

private:
    // 构造私有
    Singleton() {}
    // 程序启动就初始化
    static Singleton instance;
};

// 静态变量初始化
Singleton Singleton::instance;

int main()
{
    Singleton& s1 = Singleton::getInstance();
    Singleton& s2 = Singleton::getInstance();

    cout << &s1 << endl;
    cout << &s2 << endl; // 地址相同

    return 0;
}

优点 :简单、线程安全
缺点:不用也会创建,可能浪费资源


实现 2:懒汉式(基础版,非线程安全)

第一次使用时才创建实例。

cpp 复制代码
#include <iostream>
using namespace std;

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

    void show() { cout << "懒汉式单例" << endl; }

    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

private:
    Singleton() {}
    static Singleton* instance;
};

Singleton* Singleton::instance = nullptr;

int main()
{
    Singleton* s1 = Singleton::getInstance();
    Singleton* s2 = Singleton::getInstance();
    return 0;
}

注意 :多线程不安全,高并发会创建多个实例


实现 3:线程安全懒汉式(加锁)

C++11 线程安全版本

cpp 复制代码
#include <iostream>
#include <mutex>
using namespace std;

mutex mtx;

class Singleton
{
public:
    static Singleton* getInstance()
    {
        lock_guard<mutex> lock(mtx);
        if (instance == nullptr)
        {
            instance = new Singleton();
        }
        return instance;
    }

    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

private:
    Singleton() {}
    static Singleton* instance;
};

Singleton* Singleton::instance = nullptr;

实现 4:双检查锁 DCL(高性能线程安全)

企业最常用

cpp 复制代码
#include <iostream>
#include <mutex>
using namespace std;

class Singleton
{
public:
    static Singleton* getInstance()
    {
        if (instance == nullptr)
        {
            lock_guard<mutex> lock(mtx);
            if (instance == nullptr)
            {
                instance = new Singleton();
            }
        }
        return instance;
    }

    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

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

Singleton* Singleton::instance = nullptr;
mutex Singleton::mtx;

实现 5:C++11 最优方案 Meyers 单例(推荐!)

最简单、线程安全、无内存泄漏

cpp 复制代码
#include <iostream>
using namespace std;

class Singleton
{
public:
    static Singleton& getInstance()
    {
        static Singleton instance;
        return instance;
    }

    void show() { cout << "Meyers 单例(C++11最佳)" << endl; }

    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

private:
    Singleton() {}
};

int main()
{
    Singleton& s1 = Singleton::getInstance();
    Singleton& s2 = Singleton::getInstance();
    s1.show();
    return 0;
}

优点:

  • 线程安全(C++11 保证静态变量初始化原子性)
  • 懒加载
  • 无内存泄漏
  • 代码极简

五、单例模式自动释放(析构安全)

加入内部回收类,程序结束自动释放单例

cpp 复制代码
#include <iostream>
using namespace std;

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

    class AutoDelete
    {
    public:
        ~AutoDelete()
        {
            if (Singleton::instance)
            {
                delete Singleton::instance;
                cout << "单例已自动释放" << endl;
            }
        }
    };

private:
    Singleton() {}
    static Singleton* instance;
    static AutoDelete ad;
};

Singleton* Singleton::instance = nullptr;
Singleton::AutoDelete Singleton::ad;

六、五种单例对比总结

实现方式 线程安全 性能 推荐指数
饿汉式 安全 高 ⭐⭐⭐
基础懒汉式 不安全 高 不推荐
加锁懒汉式 安全 低 ⭐⭐
双检查锁 DCL 安全 高 ⭐⭐⭐⭐
Meyers 单例 安全 极高 ⭐⭐⭐⭐⭐

七、C++ 单例必须遵守的 4 条规则

  1. 构造函数私有化
  2. 禁用拷贝构造
  3. 禁用赋值重载
  4. 提供全局唯一访问点

八、企业最佳实践

  1. 优先使用 Meyers 单例(C++11 最优)
  2. 禁止手动 new/delete,使用智能指针或自动释放
  3. 多线程环境必须使用线程安全版本
  4. 单例不建议存放大量数据,避免内存飙升
相关推荐
2601_9628857212 分钟前
如何用 Python 做均线粘合选股?(多头发散前的变盘候选)
开发语言·python
2601_9620715717 分钟前
类变量和全局变量的隔离性有什么区别?
java·开发语言·jvm
海绵宝宝转agent24 分钟前
LeetCode100 LRU缓存思路讲解
java·开发语言·缓存
(Charon)43 分钟前
【C++面试】RAII到底是什么:从资源管理理解C++对象生命周期
c++·算法·面试
无名猿1 小时前
成员初始化列表与初始化顺序陷阱:按声明顺序,不是书写顺序
c++·现代c++·语法基础
AC赳赳老秦1 小时前
OpenClaw 与 FineBI 联动方案:公开数据自动采集与实时业务分析看板实践
大数据·开发语言·python·php·finebi·deepseek·openclaw
通信瓦工1 小时前
OCP 冷却环境与冷却剂分配单元(CDU)子项目
java·开发语言
91刘仁德1 小时前
传输层协议深度拆解:端口寻址、UDP 报文与 TCP 可靠性机制全解析
linux·网络·c++·网络协议·tcp/ip·udp·c
Liuchang09111 小时前
洛谷 P2670 [NOIP 2015 普及组] 扫雷游戏
c++·算法·游戏
坤坤子吖1 小时前
Python基础语法学习:函数
开发语言·笔记·python·学习