单例模式(Singleton Pattern)是C++中最常用的设计模式之一,属于创建型模式。它确保一个类在整个程序生命周期中只存在一个实例,并提供一个全局访问点来获取这个实例。

单例模式的核心要素

  1. 私有构造函数:防止外部直接创建对象
  2. 私有静态成员变量:存储唯一实例
  3. 公有静态成员函数:提供全局访问点

单例模式的常见实现方式

1. 饿汉式(Eager Initialization)

程序启动时就创建实例,线程安全但可能提前占用资源。

class Singleton {
private:
    // 私有构造函数
    Singleton() {}
    
    // 私有静态实例
    static Singleton instance;
    
public:
    // 禁止拷贝和赋值
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
    
    // 公有静态方法,返回实例
    static Singleton& getInstance() {
        return instance;
    }
};

// 在类外初始化静态成员
Singleton Singleton::instance;
2. 懒汉式(Lazy Initialization)

第一次使用时才创建实例,需要处理线程安全问题。

线程安全的懒汉式(C++11及以上)

class Singleton {
private:
    // 私有构造函数
    Singleton() {}
    
public:
    // 禁止拷贝和赋值
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
    
    // 公有静态方法,返回实例
    static Singleton& getInstance() {
        // 局部静态变量,C++11保证线程安全
        static Singleton instance;
        return instance;
    }
};
3. 指针版懒汉式(需要手动释放)
class Singleton {
private:
    // 私有指针
    static Singleton* instance;
    
    // 私有构造函数
    Singleton() {}
    
    // 私有析构函数
    ~Singleton() {}
    
    // 内部类,用于自动释放
    class Deleter {
    public:
        ~Deleter() {
            if (Singleton::instance) {
                delete Singleton::instance;
                Singleton::instance = nullptr;
            }
        }
    };
    static Deleter deleter;
    
public:
    // 禁止拷贝和赋值
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
    
    static Singleton* getInstance() {
        if (!instance) {
            // 双重检查锁定,提高效率
            std::lock_guard<std::mutex> lock(mutex);
            if (!instance) {
                instance = new Singleton();
            }
        }
        return instance;
    }
    
private:
    static std::mutex mutex;
};

// 初始化静态成员
Singleton* Singleton::instance = nullptr;
Singleton::Deleter Singleton::deleter;
std::mutex Singleton::mutex;

单例模式的应用场景

  1. 日志系统:确保日志写入的一致性
  2. 配置管理器:全局共享配置信息
  3. 数据库连接池:控制连接数量
  4. 设备管理器:管理唯一的硬件设备

单例模式的优缺点

优点

  • 确保唯一实例,节省系统资源
  • 提供全局访问点,方便使用
  • 避免频繁创建和销毁对象,提高性能

缺点

  • 违反单一职责原则,既负责业务逻辑又负责创建自身
  • 可能导致代码耦合度提高
  • 不易于单元测试
  • 长时间持有资源,可能影响内存使用

在实际开发中,应根据具体需求选择合适的实现方式,C++11及以上版本推荐使用局部静态变量的懒汉式,既简洁又线程安全。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐