单例模式(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. 单例不建议存放大量数据,避免内存飙升
相关推荐
blueman88885 小时前
Qt5通过vcpkg中调用时,在debug模式下调试时总是调用release的plugins文件夹中的dll
c++·qt·cmake
我是坏垠6 小时前
Crypto、Cipher与Password:Java加密开发的三个核心概念
java·开发语言·python
white_ant6 小时前
JDK LTS 版本升级迁移注意事项大全
java·开发语言
Bobolink_7 小时前
跨境业务网络环境评估,“干净、一致、独享”三个关键指标
开发语言·网络·php·跨境网络·网络环境
你怎么知道我是队长7 小时前
JavaScript的变量和数据类型介绍
开发语言·javascript·ecmascript
xingke7 小时前
C 语言多文件编程:(一)头文件、extern、编译链接
c语言·开发语言·多文件
戮漠summer8 小时前
Missing Semester 计算机教育中缺失的一课 Lecture 01 Shell
开发语言·后端·scala
jinyishu_8 小时前
C++ string使用方法
开发语言·c++
EW Frontier8 小时前
三级跳突破864维动作空间——QMIX-Hierarchical多无人机协同通信方法全解析【附python代码】
开发语言·python·无人机·强化学习·通信资源分配
名字还没想好☜8 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js