单例模式(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. 单例不建议存放大量数据,避免内存飙升
相关推荐
AI人工智能+电脑小能手1 小时前
【大白话说Java面试题 第44题】【JVM篇】第4题:什么时候会触发 Young GC?什么时候会触发 Full GC?
java·开发语言·jvm·后端·面试
c++之路1 小时前
代理模式(Proxy Pattern)
开发语言·c++·代理模式
水木流年追梦1 小时前
大模型入门-应用篇2-RAG (检索增强生成):从原理到 Python 实战
开发语言·python·算法·prompt
froginwe111 小时前
《Foundation 提示框》详解
开发语言
handler011 小时前
速通蓝桥杯省一: 前缀和&差分(附经典例题)
c语言·c++·笔记·职场和发展·蓝桥杯
谙弆悕博士1 小时前
快速学C语言——第 11 章:指针与数组
服务器·c语言·开发语言·学习方法·业界资讯·指针·数组
无限进步_1 小时前
【C++】lambda表达式与std::function/bind包装器
开发语言·c++
树下水月1 小时前
php artisan serve 在window上执行报错的问题
开发语言·php
梦梦代码精1 小时前
电商系统的核心难点:订单与营销系统如何设计?——LikeShop 架构深度拆解(规则计算与状态一致性)
java·开发语言·低代码·架构·开源·github