饿汉、饱汉、内部静态变量三种单例模式

饿汉

复制代码
一个饥饿的人,看到食物就吃。
所以类加载了就创建了实例。
特点:
    1.立即创建实例
    2.线程安全
c 复制代码
// 文件: main.cc
// 时间: 2024-07-26
// 来自: ccj
// 描述: 饿汉式单例

#include <iostream>

class Singleton {
public:
    ~Singleton() { std::cout << "~Singleton()" << std::endl; }
    static Singleton& getInstance() { return instance; }

public:
    void doSomething() { std::cout << "Doing something." << std::endl; }

private:
    Singleton() { std::cout << "Singleton()" << std::endl; }
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

private:
    static Singleton instance;
};

// 立即创建实例
Singleton Singleton::instance;

int main() {
    std::cout << "start use singleton" << std::endl;

    Singleton& instance1 = Singleton::getInstance();
    Singleton& instance2 = Singleton::getInstance();

    // 验证是否为同一个实例
    if (&instance1 == &instance2) {
        std::cout << "instance1 and instance2 are the same instance." << std::endl;
    }

    instance1.doSomething();
    instance2.doSomething();

    return 0;
}

饱汉/懒汉

复制代码
一个吃饱的人,食物可以放一会。
类先加载,在真正调用时创建实例
特点:
1.延时创建实例
2.加锁才能线程安全
3.每次获取单例会判断一次是否创建
4.要注意释放单例
c 复制代码
// 文件: main.cc
// 时间: 2024-07-26
// 来自: ccj
// 描述: 饱汉式单例

#include <iostream>
#include <mutex>

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

public:
    void doSomething() { std::cout << "Doing something." << std::endl; }

private:
    Singleton() { std::cout << "Singleton()" << std::endl; }
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

private:
    static Singleton* instance;
    static std::mutex mtx;
};

// 先不创建实例
Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mtx;

int main() {
    std::cout << "start use singleton" << std::endl;

    Singleton* instance1 = Singleton::getInstance();
    Singleton* instance2 = Singleton::getInstance();

    // 验证是否为同一个实例
    if (instance1 == instance2)
        std::cout << "instance1 and instance2 are the same instance." << std::endl;

    instance1->doSomething();
    instance2->doSomething();

    // 注意: 需要自己释放
    delete Singleton::getInstance();

    return 0;
}

内部静态变量

复制代码
C++11规定了local static在多线程条件下的初始化行为,要求编译器保证了内部静态变量的线程安全性。
特点:
1.延时创建实例
2.编译器保证线程安全
c 复制代码
// 文件: main.cc
// 时间: 2024-07-26
// 来自: ccj
// 描述: 内部静态变量单例

#include <iostream>

class Singleton {
public:
    ~Singleton() { std::cout << "~Singleton()" << std::endl; }
    static Singleton &getInstance() {
        static Singleton s;
        return s;
    }

public:
    void doSomething() { std::cout << "Doing something." << std::endl; }

private:
    Singleton() { std::cout << "Singleton()" << std::endl; }
    Singleton(const Singleton &) = delete;
    Singleton &operator=(const Singleton &) = delete;
};

int main() {
    std::cout << "start use singleton" << std::endl;

    Singleton &instance1 = Singleton::getInstance();
    Singleton &instance2 = Singleton::getInstance();

    // 验证是否为同一个实例
    if (&instance1 == &instance2)
        std::cout << "instance1 and instance2 are the same instance." << std::endl;

    instance1.doSomething();
    instance2.doSomething();

    return 0;
}

总结

复制代码
尽可能用内部静态变量单例
相关推荐
啦啦啦啦啦zzzz3 天前
设计模式:单例模式和工厂模式
c++·单例模式·设计模式·工厂模式
空杆推不起3 天前
金融数仓标准化:信贷业务 ODS/DWD/DWS/ADS/DIM 全层级建模指南
单例模式·金融
芝士熊爱编程11 天前
创建型模式-单例模式
java·单例模式·设计模式
张小姐的猫13 天前
【Linux】网络编程 —— HTTP协议(上)
linux·运维·服务器·网络·http·单例模式·策略模式
zjun100113 天前
C++:单例模式
c++·单例模式
ttod_qzstudio1 个月前
【软考设计模式】单例模式:唯一实例的管控与线程安全精讲
单例模式·设计模式
geovindu1 个月前
java: Singleton Pattern
java·开发语言·后端·单例模式·设计模式·创建型模式
重生之我是Java开发战士2 个月前
【Java SE】多线程(三):单例模式,阻塞队列,线程池与定时器
java·javascript·单例模式
许彰午2 个月前
34_Java设计模式之单例模式
java·单例模式·设计模式
罗超驿2 个月前
10.Java单例模式全解析:饿汉式与懒汉式实现及线程安全深度剖析
安全·单例模式·javaee