两种单例模式的区别

发布于:2024-05-31 ⋅ 阅读:(155) ⋅ 点赞:(0)

看两个栗子

传统指针版单例模式
class Singleton {
private:
    // 私有化构造函数
    Singleton() {}

    // 禁止拷贝构造函数
    Singleton(const Singleton&) = delete;

    // 禁止拷贝赋值操作
    Singleton& operator=(const Singleton&) = delete;

    // 静态变量,存储唯一实例
    static Singleton* instance;

public:
    // 静态方法,用于获取实例
    static Singleton* getInstance() {
        if (instance == nullptr) {
            instance = new Singleton();
        }
        return instance;
    }

    // 其他成员函数
    void Display() {
        //...
    }
};

// 在类外初始化静态成员变量
Singleton* Singleton::instance = nullptr;

int main() {
    // 获取单例类的实例
    Singleton* mySingleton = Singleton::getInstance();
    mySingleton->Display();
}
现代静态变量版单例模式
class Singleton {
private:
    // 私有化构造函数
    Singleton() {}

    // 禁止拷贝构造函数
    Singleton(const Singleton&) = delete;

    // 禁止拷贝赋值操作
    Singleton& operator=(const Singleton&) = delete;

public:
    // 静态方法,用于获取实例
    static Singleton& getInstance() {
        static Singleton instance;
        return instance;
    }

    // 其他成员函数
    void Display() {
        //...
    }
};

int main() {
    // 获取单例类的实例
    Singleton& mySingleton = Singleton::getInstance();
    mySingleton.Display();
}

分析

💥两种单例模式的优劣和区别:

  1. 简洁性
  • 传统指针版:需要手动管理指针(如初始化和销毁),代码稍复杂。
  • 现代静态变量版:代码简洁,避免了指针管理。
  1. 线程安全
  • 传统指针版:在多线程环境下,手动管理静态实例的创建需要考虑线程安全问题,通常需要加入互斥锁。
  • 现代静态变量版:C++11 以后,局部静态变量的初始化是线程安全的,天然支持多线程环境。
  1. 内存管理
  • 传统指针版:需要显式删除静态实例对象,避免内存泄漏。
  • 现代静态变量版:局部静态变量由编译器自动管理其生命周期,不需要手动删除。

🎉推荐:
在大多数情况下,我更推荐使用现代静态变量版的单例模式,原因如下:

  1. 简洁明了:代码更简洁,更容易理解和维护。
  2. 线程安全:C++11 及其之后版本保证了线程安全的初始化。
  3. 自动内存管理:不需要手动管理内存,减少了内存泄漏的风险。

然而,在某些特定场景下,可能会有不同的考虑。例如,如果你需要在单例销毁时执行特殊的清理操作或需要在不支持 C++11 的编译器上编译代码,那么传统的单例模式可能会更适合。

结论

现代静态变量版的单例模式在大多数情境下都更符合当前的开发需求和标准,推荐优先采用。但在设计模式的选择上仍需根据具体需求和环境进行适当的调整。


网站公告

今日签到

点亮在社区的每一天
去签到