Linux(十三)设计模式——单例模式

本文介绍了设计模式中的单例模式,用于确保一个类只有一个实例。详细讲解了饿汉模式和懒汉模式的实现,饿汉模式在类装载时就完成了初始化,而懒汉模式则在首次使用时才创建对象,后者更节省内存但需要注意线程安全问题。文章还讨论了两种模式的优缺点及线程安全的实现策略。
摘要由CSDN通过智能技术生成

 设计模式——针对典型场景所设计出来的特别的处理方案

单例模式:一个类只能实例化一个对象(所以叫单例)

        场景:

                1、资源角度:资源在内存中只占有一份

                2、数据角度:如果只有一个对象,那么该对象在什么时候访问它的资源都是一致的

目录

 实现方式

一、饿汉模式

二、懒汉模式


就比如任务管理器,我再怎么重复打开它,它也只有这一份任务管理器。

 实现方式

 一、饿汉模式

所谓饿汉模式,直接将对象实例化完毕,用的时候直接就使用了(空间换时间)

        好处:效率最大化,资源用的时候直接就用了(不涉及线程安全问题)

        缺点:初始化速度慢,占用内存多

实现:使用静态成员变量(保证它在初始化就能有一份内存)

           将构造函数私有化(类外无法实例化对象,对象只能有一份)

           提供public接口进行访问

#include <iostream>

class Singleton
{
private:
    int _data;

private:
    static Singleton eton;
    Singleton() // 将构造函数私有化,意味着在类外无法实例化对象
    {           // 保证一个类只能实例化一个对象(构造函数私有化,该类也无法被继承)
        // 逻辑处理begin
        _data = 100;
        // 逻辑处理end
    }

public:
    static Singleton *GetInstence() // 静态成员只能被静态成员函数调用
    {
        return &eton;
    }
    int Get_data()    // 提供一个获取data的方法
    {
        return _data;
    }
};

// 静态成员变量,类内声明、类外定义
Singleton Singleton::eton;

int main()
{
    Singleton *eton = Singleton::GetInstence();
    std::cout << eton->Get_data() << std::endl;

    return 0;
}

二、懒汉模式

所谓懒汉模式,就是等待用的时候才去进行构造,才去进行实例化

        优点:内存资源占用少,初始化效率高

        缺点:需要访问资源的时候需要去实例化对象加载(第一次访问时对象时比较慢)(涉及线程安全问题)

实现:

        1、构造函数私有化(保证只能实例化一个对象)

        2、定义静态类型的指针,在用的时候进行new

        3、new的时候注意线程安全问题(加锁保护)

        4、避免已经实例化之后后续资源重复加解锁访问(double check)

        5、使用volatile修饰,避免编译器过度优化

                volatile:当一个变量经常被cpu访问,那就把这个变量放入一个寄存器中,这样对于这样一个高频访问的变量,cpu就可以直接从寄存器中访问,避免了来回从内存中拿取数据。

#include <iostream>
#include <mutex>

class Singleton
{
private:
    int _data;

private:
    static Singleton *_eton; // 1、定义静态的指针与锁
    static std::mutex _mutex;
    Singleton() /// 2、构造函数私有化(只能被实例化一次)
    {
        // 逻辑处理begin
        _data = 100;
        // 逻辑处理end
    }

public:
    int get_data() { return _data; }
    static Singleton *GetInsetnce()
    {
        if (_eton == nullptr) // 5、double check避免了已经实例化了还需要加解锁问题
        {
            _mutex.lock(); /// 4、使用mutex进行安全控制
            if (_eton == nullptr)
                _eton = new Singleton; // 3、等到用的时候进行new 调用构造实例化
            _mutex.unlock();
        }
        return _eton;
    }
};
// 6、对其构造和声明使用volatile修饰 保证数据的可见性
// volatile Singleton *Singleton::_eton = nullptr;
Singleton *Singleton::_eton = nullptr;
std::mutex Singleton::_mutex;

int main()
{
    Singleton *eton = Singleton::GetInsetnce();
    std::cout << eton->get_data() << std::endl;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值