C++的单例模式

忘记之前有没有写过单例模式了。

再记录一下:

我使用的代码:

cpp 复制代码
#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

双锁单例:

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

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;
}

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

双检锁(Double Checked Locking):

优点:

线程安全。

在实例已经被创建之后,直接返回实例,避免了每次获取实例时都需要获取锁的开销。

缺点:

代码相对复杂。

在某些老的编译器或硬件架构上,双检锁可能无法正常工作,可能需要内存屏障或其他同步机制。

静态局部变量(Meyers' Singleton):
cpp 复制代码
class Singleton {
public:
    static Singleton& getInstance() {
        static Singleton instance;
        return instance;
    }
private:
    Singleton() {}
};

优点:

线程安全(在 C++11 及以后的版本中)。

代码简单、清晰。

延迟初始化:只有在首次调用 getInstance 时,实例才会被创建。

缺点:

对于老的 C++ 标准(C++11 之前),这种方法可能不是线程安全的。

饿汉式:
cpp 复制代码
class Singleton {
private:
    static Singleton instance;
    Singleton() {}
public:
    static Singleton& getInstance() {
        return instance;
    }
};

优点:

线程安全,因为实例在程序开始时就已经被初始化。

代码简单。

缺点:

实例在程序开始时就被创建,即使它从未被使用,可能会导致不必要的资源占用或初始化开销。

懒汉式(简单):
cpp 复制代码
class Singleton {
private:
    static Singleton* instance;
    Singleton() {}
public:
    static Singleton* getInstance() {
        if (!instance) {
            instance = new Singleton();
        }
        return instance;
    }
};

优点:

实现简单。

延迟初始化,只在首次获取实例时创建。

缺点:

非线程安全。如果多个线程同时尝试创建实例,可能导致多个实例被创建。

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

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

相关推荐
deng-c-f1 小时前
Linux C/C++ 学习日记(53):原子操作(二):实现shared_ptr
开发语言·c++·学习
一个不知名程序员www1 小时前
算法学习入门---结构体和类(C++)
c++·算法
墨雪不会编程2 小时前
C++ string 详解:STL 字符串容器的使用技巧
java·开发语言·c++
yangpipi-3 小时前
《C++并发编程实战》第5章 C++内存模型和原子操作
android·java·c++
SunkingYang3 小时前
MFC进程间消息通信深度解析:SendMessage、PostMessage与SendNotifyMessage的底层实现与实战指南
c++·mfc·共享内存·通信·postmessage·sendmessage·进程间
XFF不秃头4 小时前
力扣刷题笔记-旋转图像
c++·笔记·算法·leetcode
王老师青少年编程4 小时前
csp信奥赛C++标准模板库STL案例应用3
c++·算法·stl·csp·信奥赛·lower_bound·标准模版库
Tim_105 小时前
【C++入门】04、C++浮点型
开发语言·c++
hkNaruto5 小时前
【C++】记录一次C++程序编译缓慢原因分析——滥用stdafx.h公共头文件
开发语言·c++
柏木乃一5 小时前
进程(6)进程切换,Linux中的进程组织,Linux进程调度算法
linux·服务器·c++·算法·架构·操作系统