创建型模式

         有些情况下,我们对于一个类,并不希望他在程序里出现太多的实例,我们只希望这个类是只有一个实例。

        举个简单的例子,比方说电脑的回收站,他不能像文件夹一样打开多个,他只能存在一个。这种具有唯一性的,就是单例要想做到的。它类似于全局变量,却又不是全局变量。

特点

        1.保证一个类只有一个实例。

        2.为该实例提供一个全局访问节点

示例

这里简单提供两种实现方法。

        饿汉式

// 1. 饿汉式单例(线程安全,编译时初始化)
class SingletonHungry {
private:
    // 私有构造函数
    SingletonHungry() {
        std::cout << "Hungry Singleton initialized" << std::endl;
    }
    
    // 禁止拷贝和赋值
    SingletonHungry(const SingletonHungry&) = delete;
    SingletonHungry& operator=(const SingletonHungry&) = delete;
    
    // 静态实例(编译时初始化)
    static SingletonHungry instance;

public:
    // 全局访问点
    static SingletonHungry& getInstance() {
        return instance;
    }
    
    void doSomething() {
        std::cout << "Hungry Singleton doing something" << std::endl;
    }
};
// 初始化静态成员
SingletonHungry SingletonHungry::instance;

        懒汉式

// 2. 懒汉式单例(非线程安全,延迟初始化)
class SingletonLazy {
private:
    static SingletonLazy* instance;
    
    // 私有构造函数
    SingletonLazy() {
        std::cout << "Lazy Singleton initialized" << std::endl;
    }
    
    // 禁止拷贝和赋值
    SingletonLazy(const SingletonLazy&) = delete;
    SingletonLazy& operator=(const SingletonLazy&) = delete;

public:
    // 全局访问点(非线程安全)
    static SingletonLazy* getInstance() {
        if (instance == nullptr) {
            instance = new SingletonLazy();
        }
        return instance;
    }
    
    // 销毁实例(可选)
    static void destroyInstance() {
        if (instance != nullptr) {
            delete instance;
            instance = nullptr;
        }
    }
    
    void doSomething() {
        std::cout << "Lazy Singleton doing something" << std::endl;
    }
};

// 初始化静态成员
SingletonLazy* SingletonLazy::instance = nullptr;

饿汉式与懒汉式区别

  1. 饿汉式单例

    • 特点:在程序启动时(类加载时)就完成初始化
    • 优点:实现简单,天然线程安全
    • 缺点:可能提前占用资源,若单例初始化耗时会影响程序启动速度
    • 适用场景:单例对象较小,初始化较快的情况
  2. 基础懒汉式

    • 特点:第一次使用时才初始化(延迟加载)
    • 优点:节省资源,避免不必要的初始化
    • 缺点:非线程安全,多线程环境下可能创建多个实例
    • 适用场景:单线程环境

优势

        1.你可以保证你一个类只有一个实例

        2.你获得了一个指向该实例的全局访问节点。

        3.仅在首次请求单例对象时对其进行初始化。

Logo

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

更多推荐