23种设计模式 - 单例模式(Singleton)

单例模式(Singleton)------ 全局就我一个,多了没有,爱用不用

大白话解释

想象一个公司只有一台打印机。不管谁来打印,用的都是同一台机器。如果每次有人要打印就新买一台,那公司得破产。

单例模式就是:整个程序运行期间,某个类只能有一个实例,所有人都共用这一个。

常见场景:

  • 配置文件管理器(配置只需加载一次)
  • 日志系统(全局写同一个日志)
  • 数据库连接池(连接资源宝贵)
  • 窗口管理器(只有一个主窗口)

核心思路

  1. 把构造函数藏起来 (设为 private),外面没法 new 出来
  2. 自己内部保存唯一实例
  3. 提供一个全局访问点(静态方法)

C++ 代码示例

版本一:懒汉式(用到的时候才创建)

cpp 复制代码
#include <iostream>
#include <string>

class ConfigManager {
private:
    // 私有构造函数,外部无法直接 new
    ConfigManager() {
        std::cout << "配置管理器初始化完成!\n";
        dbHost = "localhost";
        dbPort = 3306;
    }

    // 禁止拷贝和赋值(C++11 写法)
    ConfigManager(const ConfigManager &) = delete;
    ConfigManager &operator=(const ConfigManager &) = delete;

    std::string dbHost;
    int dbPort;

public:
    // 全局访问点:第一次调用时创建实例
    static ConfigManager &instance() {
        static ConfigManager instance; // C++11 保证线程安全
        return instance;
    }

    std::string getDbHost() const { return dbHost; }
    int getDbPort() const { return dbPort; }

    void setDbHost(const std::string& host) { dbHost = host; }
};

int main() {
    // 获取单例
    ConfigManager &config1 = ConfigManager::instance();
    ConfigManager &config2 = ConfigManager::instance();

    // 验证是同一个对象
    std::cout << "是同一个对象吗?" << (&config1 == &config2 ? "是" : "否") << "\n";

    // 通过 config1 修改
    config1.setDbHost("192.168.0.100");

    // config2 也能看到修改(因为本来就是同一个)
    std::cout << "config2 的数据库地址:" << config2.getDbHost() << "\n";

    return 0;
}

输出:

复制代码
配置管理器初始化完成!
是同一个对象吗?是
config2 的数据库地址:192.168.0.100

版本二:线程安全的指针版(多线程环境)

cpp 复制代码
#include <iostream>
#include <mutex>

class Logger {
private:
    static Logger *instance;
    static std::mutex mtx;

    Logger() {
        std::cout << "日志系统启动\n";
    }

public:
    static Logger *instance() {
        if (instance == nullptr) {           // 第一次检查(提高效率)
            std::lock_guard<std::mutex> lock(mtx);
            if (instance == nullptr) {       // 第二次检查(保证线程安全)
                instance = new Logger();
            }
        }
        return instance;
    }

    void log(const std::string &msg) {
        std::cout << "[LOG] " << msg << "\n";
    }
};

// 静态成员初始化
Logger *Logger::instance = nullptr;
std::mutex Logger::mtx;

int main() {
    Logger::instance()->log("程序启动");
    Logger::instance()->log("用户登录成功");
    return 0;
}

优缺点

说明
✅ 优点 节约资源,避免重复创建
✅ 优点 全局共享资源,防止冲突
✅ 优点 控制访问,全局只有一个入口
❌ 缺点 没有接口,没有继承,很难扩展新功能
❌ 缺点 单元测试困难(全局状态难以隔离)
❌ 缺点 生命周期管理不灵活,一旦创建,无法手动销毁、重启
❌ 缺点 到处都能直接调用,代码可读性变差,难以清理依赖
相关推荐
2301_803554522 小时前
单例模式以及面试可能问的--精写
单例模式·面试·职场和发展
Serene_Dream4 小时前
深度解析设计模式:单例模式(Singleton Pattern)
单例模式·设计模式
白藏y4 小时前
【C++】特殊类设计与单例模式
c++·单例模式
朱一头zcy4 小时前
设计模式入门:最简单的单例模式
笔记·单例模式·设计模式
柏木乃一1 天前
Linux线程(8)基于单例模式的线程池
linux·运维·服务器·c++·单例模式·操作系统·线程
for_ever_love__1 天前
Objective-C 学习 单例模式
学习·ios·单例模式·objective-c
夕珩2 天前
单例模式、原型模式、工厂方法模式、抽象工厂模式、建造者模式、解释器模式、命令模式
单例模式·解释器模式·建造者模式·工厂方法模式·抽象工厂模式·命令模式·原型模式
JTCC3 天前
Java 设计模式西游篇 - 第一回:单例模式显神通 悟空巧解资源劫
java·单例模式·设计模式
geovindu4 天前
python: Singleton Pattern
开发语言·python·单例模式·设计模式