C++设计模式之单例模式

1.介绍

单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来获取这个实例。其核心思想是将类的实例化过程进行严格控制,使得在整个程序运行期间,该类只能创建一个对象实例。这样做的好处是可以避免多个实例带来的资源浪费和数据不一致问题,同时方便对这个唯一实例进行全局访问。它常用于需要全局唯一对象的场景,如配置管理、日志记录、数据库连接池等。

2.单例模式的关键点

1.私有构造函数:防止外部直接实例化。

2.静态实例:类内部维护一个静态实例。

3.全局访问点:通过静态方法提供实例访问。

3.单例模式的实现方式

(1)懒汉式。实例在第一次使用时创建,延迟加载。

cpp 复制代码
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 doSomething() {
        // 示例方法
    }
};

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

问题:非线程安全,多线程环境下可能创建多个实例。

(2)饿汉式。类加载时即创建实例,避免多线程问题。

cpp 复制代码
class Singleton {
private:
    // 私有构造函数
    Singleton() {}

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

    // 静态实例
    static Singleton instance;

public:
    // 全局访问点
    static Singleton* getInstance() {
        return &instance;
    }

    void doSomething() {
        // 示例方法
    }
};

// 初始化静态成员变量
Singleton Singleton::instance;

(3)双重检查锁。结合懒汉式和同步锁,确保线程安全且高效。

cpp 复制代码
#include <mutex>

class Singleton {
private:
    // 私有构造函数
    Singleton() {}

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

    // 静态实例指针
    static Singleton* instance;
    static std::mutex mtx;

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

    void doSomething() {
        // 示例方法
    }
};

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

优点:线程安全且仅在第一次访问时同步。

(4)Meyer's Singleton(静态局部变量)利用C++的静态局部变量特性,实现线程安全的单例模式。

cpp 复制代码
class Singleton {
private:
    // 私有构造函数
    Singleton() {}

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

public:
    // 全局访问点
    static Singleton& getInstance() {
        static Singleton instance;
        return instance;
    }

    void doSomething() {
        // 示例方法
    }
};

优点:线程安全(C++11 及以上标准保证静态局部变量的线程安全性)。延迟加载,代码简介。

(5)智能指针单例模式。使用share_ptr或unique_ptr管理单例实例,避免内存泄漏。

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

class Singleton {
private:
    // 私有构造函数
    Singleton() {}

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

    // 静态智能指针实例
    static std::shared_ptr<Singleton> instance;
    static std::mutex mtx;

public:
    // 全局访问点
    static std::shared_ptr<Singleton> getInstance() {
        if (instance == nullptr) {
            std::lock_guard<std::mutex> lock(mtx);
            if (instance == nullptr) {
                instance = std::shared_ptr<Singleton>(new Singleton());
            }
        }
        return instance;
    }

    void doSomething() {
        // 示例方法
    }
};

// 初始化静态成员变量
std::shared_ptr<Singleton> Singleton::instance = nullptr;
std::mutex Singleton::mtx;

优点:使用智能指针自动管理内存,避免手动释放。

4.总结
  • 推荐使用 Meyer's Singleton(静态局部变量),简洁且线程安全。

  • 如果需要动态内存管理,可以使用智能指针单例模式

  • 在多线程环境下,务必确保线程安全,可以使用双重检查锁静态局部变量

如有错误,敬请指正!!!

相关推荐
小吕学编程1 小时前
策略模式实战:Spring中动态选择商品处理策略的实现
java·开发语言·设计模式
pan_junbiao1 小时前
Spring框架的设计模式
java·spring·设计模式
zh_xuan9 小时前
c++ 单例模式
开发语言·c++·单例模式
蔡蓝15 小时前
设计模式-建造者模式
服务器·设计模式·建造者模式
不伤欣20 小时前
游戏设计模式 - 子类沙箱
游戏·unity·设计模式
漫谈网络20 小时前
MVC与MVP设计模式对比详解
设计模式·mvc
蔡蓝20 小时前
设计模式-观察着模式
java·开发语言·设计模式
西北大程序猿21 小时前
单例模式与锁(死锁)
linux·开发语言·c++·单例模式
哆啦A梦的口袋呀1 天前
基于Python学习《Head First设计模式》第六章 命令模式
python·学习·设计模式
半路下车1 天前
【Harmony OS 5】HarmonyOS应用测试指南
设计模式·harmonyos