• C++的单例模式


    忘记之前有没有写过单例模式了。
    再记录一下:
    我使用的代码:

    #ifndef SINGLETON_MACRO_HPP
    #define SINGLETON_MACRO_HPP
    
    #define SINGLETON_DECL(class_name) \
    public: \
        static class_name& instance() { \
            static class_name s_instance; \
            return s_instance; \
        } \
    private: \
        class_name();\
        class_name(const class_name&) = delete; \
        class_name& operator=(const class_name&) = delete;
    
    #endif // SINGLETON_MACRO_HPP
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    双锁单例:

    #include 
    #include 
    
    class Singleton {
    private:
        static Singleton* instance;
        static std::mutex mtx;
    
        // 私有化构造函数,确保不能在类外部进行实例化
        Singleton() {}
    
    public:
        // 删除复制构造函数和复制赋值操作符
        Singleton(const Singleton& other) = delete;
        Singleton& operator=(const Singleton& other) = delete;
    
        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;
    
    int main() {
        Singleton* s1 = Singleton::getInstance();
        Singleton* s2 = Singleton::getInstance();
    
        if (s1 == s2) {
            std::cout << "Both instances are identical." << std::endl;
        } else {
            std::cout << "Instances are different." << std::endl;
        }
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    单例模式的不同实现方式各有优缺点

    双检锁(Double Checked Locking):

    优点:
    线程安全
    在实例已经被创建之后,直接返回实例,避免了每次获取实例时都需要获取锁的开销。
    缺点:
    代码相对复杂。
    在某些老的编译器或硬件架构上,双检锁可能无法正常工作,可能需要内存屏障或其他同步机制。

    静态局部变量(Meyers’ Singleton):
    class Singleton {
    public:
        static Singleton& getInstance() {
            static Singleton instance;
            return instance;
        }
    private:
        Singleton() {}
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    优点:
    线程安全(在 C++11 及以后的版本中)。
    代码简单、清晰。
    延迟初始化:只有在首次调用 getInstance 时,实例才会被创建。
    缺点:
    对于老的 C++ 标准(C++11 之前),这种方法可能不是线程安全的。

    饿汉式:
    class Singleton {
    private:
        static Singleton instance;
        Singleton() {}
    public:
        static Singleton& getInstance() {
            return instance;
        }
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    优点:
    线程安全,因为实例在程序开始时就已经被初始化。
    代码简单。
    缺点:
    实例在程序开始时就被创建,即使它从未被使用,可能会导致不必要的资源占用或初始化开销。

    懒汉式(简单):
    class Singleton {
    private:
        static Singleton* instance;
        Singleton() {}
    public:
        static Singleton* getInstance() {
            if (!instance) {
                instance = new Singleton();
            }
            return instance;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    优点:
    实现简单。
    延迟初始化,只在首次获取实例时创建。
    缺点:
    非线程安全。如果多个线程同时尝试创建实例,可能导致多个实例被创建。

    在实际的使用场景中,要根据具体的需求和上下文来选择合适的实现方法。例如,如果线程安全性很重要,那么使用双检锁或C++11及以后版本的静态局部变量方法可能更合适。

    最后问题:我用的是什么模式??

  • 相关阅读:
    基于SpringBoot+Vue的疫苗接种管理系统
    Clickhouse MAP类型
    笔记本电脑配置知识大全
    C# 根据两点名称,寻找两短路程的最优解,【有数据库设计,完整代码】
    判定转状态+序列问题上树形dp:0909T2
    2022年大家都说智慧工地好,那么智慧工地有哪些令人惊艳的应用价值?
    目前最火的人工神经网络,神经网络软件有哪些
    【Python】学生管理系统——详细解释+代码+详细注释(课设必过)
    `算法题解` `AcWing` 4611. 串联数字
    KD02策略丨涨跌幅统计+短线离场构建交易模型
  • 原文地址:https://blog.csdn.net/tayuC/article/details/132586978