当前位置: 首页 > article >正文

什么是单例模式?

什么是单例模式呢?

在一个项目中,全局范围内,某个类的实力有且仅有一个,通过这个唯一实例想其他模块提供数据的全局访问,这种模式就叫单例模式。

由于是单例,所以说不能在外部随意调用构造函数,因此要做如下处理:

构造函数私有化,在类内部只调用一次,这个是可控的。

        由于使用者在类外部不能使用构造函数,所以在类内部创建的这个唯一的对象必须是静态的,这样就可以通过类型来访问了,为了不破坏类的封装,我们都会把这个静态对象的访问权限设置为私有的。

        在类中只有它的静态成员函数才能访问其静态成员变量,所以可以给这个单例类提供一个静态成员函数用于得到这个静态的单例对象。

拷贝函数私有化或者禁用(使用delete)

拷贝赋值操作符重载函数私有化或者禁用

同时单例模式又分为两种处理模式:

饿汉模式

懒汉模式

饿汉模式就是在类加载的时候立刻进行实例化,这样就得到了一个唯一的可用对象。

饿汉模式下是没有线程安全问题的,因为在这种模式下访问单例对象的时候,这个对象已经被创建出来了。

// 饿汉模式
class TaskQueue
{
public:
    // = delete 代表函数禁用, 也可以将其访问权限设置为私有
    TaskQueue(const TaskQueue& obj) = delete;
    TaskQueue& operator=(const TaskQueue& obj) = delete;
    static TaskQueue* getInstance()
    {
        return m_taskQ;
    }
private:
    TaskQueue() = default;
    static TaskQueue* m_taskQ;
};
// 静态成员初始化放到类外部处理
TaskQueue* TaskQueue::m_taskQ = new TaskQueue;

int main()
{
    TaskQueue* obj = TaskQueue::getInstance();
}

懒汉模式是在类加载的时候不去创建这个唯一的实例,而是需要使用的时候再进行实例化。

但是懒汉模式下有线程安全问题,解决的方法有两个:双重检查锁定和静态局部变量。

双重检查锁定的实现流程建议直接去看大丙老师的视频,更容易理解。

静态局部变量:

class TaskQueue
{
public:
    // = delete 代表函数禁用, 也可以将其访问权限设置为私有
    TaskQueue(const TaskQueue& obj) = delete;
    TaskQueue& operator=(const TaskQueue& obj) = delete;
    static TaskQueue* getInstance()
    {
        static TaskQueue taskQ;
        return &taskQ;
    }
    void print()
    {
        cout << "hello, world!!!" << endl;
    }

private:
    TaskQueue() = default;
};

int main()
{
    TaskQueue* queue = TaskQueue::getInstance();
    queue->print();
    return 0;
}


http://www.kler.cn/news/317692.html

相关文章:

  • 用最新的C++技术,如何实现一个序列化工具库?
  • CSS的盒子模型(Box Model)
  • 2024年最强网络安全学习路线,详细到直接上清华的教材!
  • sftp上传文件报错提示“Permission denied“
  • geodatatool(地图资源下载工具)3.8更新
  • JavaScript 网页设计案例详解( 最新技术趋势)
  • jmeter本身常用性能优化方法
  • JavaWeb校园二手交易平台
  • 统信服务器操作系统【qcow2 镜像空间扩容】方案
  • Stable Diffusion Fooocus批量绘图脚本
  • 【深度学习|地学应用】glacier——让我们一起看看深度学习在冰川研究中的应用是怎么样的呢?
  • 【ANTLR】核心语法标记
  • Vue + element-ui实现动态表单项以及动态校验规则
  • 数据库1-1、1-n 、n-n关系实际场景
  • 如何用Stable Diffusion XL模型,绘制精致的二次元插图,学完就能用!
  • Ansible部署与应用基础
  • Nginx的相关细节
  • 【Elasticsearch】-spring boot 依赖包冲突问题
  • dedecms靶场(四种webshell姿势
  • 如何使用 Visual Studio Code 将工作效率提升 200%
  • 封装Progress 组件
  • 爬虫到底难在哪里?
  • Linux 进程3
  • 手机在网状态查询接口如何用C#进行调用?
  • 【d48】【Java】【力扣】LCR 123. 图书整理 I
  • 在 Webpack 中配置多入口应用并实现公共依赖的提取
  • 安卓13修改设置设备型号和设备名称分析与更改-android13设置设备型号和设备名称更改
  • 网络安全与国家安全的关系
  • 计算机视觉实战项目4(图像分类+目标检测+目标跟踪+姿态识别+车道线识别+车牌识别+无人机检测+A*路径规划+单目测距与测速+行人车辆计数等)
  • SpringBoot | Maven快速上手