在单例模式中,饿汉模式和懒汉模式是两种常见的实现方式,它们的区别在于实例化的时机和线程安全性。

  1. 饿汉模式(Eager Initialization):
    • 在程序启动时或类被加载时就创建实例对象。
    • 优点是实现简单,线程安全,不需要考虑多线程同步的问题。
    • 缺点是如果该实例一直没有被使用,会造成资源的浪费。
class Singleton {
private:
    static Singleton* instance;
    Singleton() {}  // 私有构造函数,防止外部实例化

public:
    static Singleton* getInstance() {
        return instance;
    }
};

Singleton* Singleton::instance = new Singleton();  // 在类定义外进行实例化
  1. 懒汉模式(Lazy Initialization):
    • 在第一次使用时才创建实例对象。
    • 优点是延迟实例化,节省了资源。
    • 缺点是在多线程环境下需要考虑线程安全性,需要使用同步机制来保证只有一个线程创建实例。
class Singleton {
private:
    static Singleton* instance;
    Singleton() {}  // 私有构造函数,防止外部实例化

public:
    static Singleton* getInstance() {
        if (instance == nullptr) {
            instance = new Singleton();
        }
        return instance;
    }
};

Singleton* Singleton::instance = nullptr;  // 在类定义外初始化为nullptr

// 懒汉模式的线程安全实现
// 使用互斥锁保证多线程环境下只有一个线程创建实例
class Singleton {
private:
    static Singleton* instance;
    static std::mutex mtx;
    Singleton() {}  // 私有构造函数,防止外部实例化

public:
    static Singleton* getInstance() {
        if (instance == nullptr) {
            std::lock_guard<std::mutex> lock(mtx);
            if (instance == nullptr) {
                instance = new Singleton();
            }
        }
        return instance;
    }
};

Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mtx;

总结:饿汉模式在程序启动或类加载时就创建实例,线程安全但可能浪费资源;懒汉模式在第一次使用时才创建实例,节省资源但需要考虑线程安全性。选择哪种方式取决于具体的需求和场景。