【C++基础】单例模式

这篇具有很好参考价值的文章主要介绍了【C++基础】单例模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文章参考:单例模式 - 巴基速递 | 爱编程的大丙

什么是单例模式

在一个项目中,全局范围内,某个类的实例有且仅有一个,通过这个唯一实例向其他模块提供数据的全局访问,这种模式就叫单例模式。单例模式的典型应用就是任务队列。

如果使用单例模式,首先要保证这个类的实例有且仅有一个。因此,就必须采取一系列的防护措施。涉及一个类多对象操作的函数有以下几个:

构造函数:创建一个新的对象
拷贝构造函数:根据已有对象拷贝出一个新的对象
拷贝赋值操作符重载函数:两个对象之间的赋值

解决措施如下:

构造函数私有化,在类内部只调用一次
拷贝构造函数私有化或者禁用(使用 = delete)
拷贝赋值操作符重载函数私有化或者禁用

由于使用者在类外部不能使用构造函数,所以在类内部创建的这个唯一的对象必须是静态的,这样就可以通过类名来访问了,为了不破坏类的封装,我们都会把这个静态对象的访问权限设置为私有的。
在类中只有它的静态成员函数才能访问其静态成员变量,所以可以给这个单例类提供一个静态函数用于得到这个静态的单例对象。

饿汉模式

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

class Singleton
{
public:
    Singleton(const Singleton& obj) = delete;  //禁止拷贝构造
    Singleton& operator=(const Singleton& obj) = delete;   //禁止运算符重载
    static Singleton* getInstance()
    {
        return m_obj;
    }
private:
    Singleton() = default;  //默认构造函数为私有
    static Singleton* m_obj;
};

Singleton* Singleton::m_obj = new Singleton;

int main()
{
    Singleton* m_obj = Singleton::getInstance();
}

注意:类的静态成员变量在使用之前必须在类的外部进行初始化才能使用

饿汉模式优点简单、线程安全,但其缺点是可能会浪费一些系统资源(单例对象在应用程序启动时就被创建,即使在某些情况下可能永远不会被使用),不支持延迟加载,不适用于需要根据运行时条件来创建单例对象的情况

懒汉模式

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

class LazySingleton
{
public:
    LazySingleton(const LazySingleton& obj) = delete;  //禁止拷贝构造
    LazySingleton& operator=(const LazySingleton& obj) = delete;   //禁止运算符重载
    static LazySingleton* getInstance()
    {
        if (m_obj == nullptr)   
            m_obj = new LazySingleton;
        return m_obj;
    }

private:
    LazySingleton() = default;  //默认构造函数为私有
    static  LazySingleton* m_obj;
};

LazySingleton* LazySingleton::m_obj = nullptr;

采用懒汉模式时,在调用getInstance()函数获取单例对象的时候,如果在单线程情况下是没有什么问题的,如果是多个线程,调用这个函数去访问单例对象就有问题了。假设有三个线程同时执行了getInstance()函数,在这个函数内部每个线程都会new出一个实例对象。此时,这个任务队列类的实例对象不是一个而是3个,很显然这与单例模式的定义是相悖的。

故其懒汉模式存在线程安全问题

懒汉模式的线程安全问题

双重检查锁定方法

最常用的解决方案就是使用互斥锁。可以将创建单例对象的代码使用互斥锁锁住。

并且在加锁、解锁的代码块外层添加了一个if判断,
其中外层if判断的目的:
这样当任务队列的实例被创建出来之后,访问这个对象的线程就不会再执行加锁和解锁操作了
内层的if判断的目的
对于第一次创建单例对象的时候线程之间还是具有竞争关系

class LazySingleton
{
public:
    LazySingleton(const LazySingleton& obj) = delete;  //禁止拷贝构造
    LazySingleton& operator=(const LazySingleton& obj) = delete;   //禁止运算符重载
    static LazySingleton* getInstance()
    {
        if (m_obj == nullptr) {
            std::lock_guard<std::mutex> lock(m_mutex);  //加锁
            if (m_obj == nullptr)
            m_obj = new LazySingleton;
        }
            
        return m_obj;
    }

private:
    LazySingleton() = default;  //默认构造函数为私有
    static  LazySingleton* m_obj;
    static std::mutex m_mutex;
};

LazySingleton* LazySingleton::m_obj = nullptr;
静态局部对象

C++11保证了局部静态变量的初始化在多线程环境中是线程安全的。这是一个简单且安全的单例模式实现方式。 

class LazySingleton
{
public:
    LazySingleton(const LazySingleton& obj) = delete;  //禁止拷贝构造
    LazySingleton& operator=(const LazySingleton& obj) = delete;   //禁止运算符重载
    static LazySingleton* getInstance()
    {
        static LazySingleton m_obj;            
        return m_obj;
    }

private:
    LazySingleton() = default;  //默认构造函数为私有
};

懒汉模式的缺点是在创建实例对象的时候有安全问题,但这样可以减少内存的浪费(如果用不到就不去申请内存了)。文章来源地址https://www.toymoban.com/news/detail-732979.html

到了这里,关于【C++基础】单例模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++的单例模式

    忘记之前有没有写过单例模式了。 再记录一下: 我使用的代码: 双锁单例: 单例模式的不同实现方式各有优缺点 双检锁(Double Checked Locking): 优点: 线程安全。 在实例已经被创建之后,直接返回实例,避免了每次获取实例时都需要获取锁的开销。 缺点: 代码相对复杂

    2024年02月10日
    浏览(46)
  • C++ 单例模式

    C++ 单例模式跟Java中的单例模式没什么区别 什么是单例?  单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例 什么时候使用单例 1个类里面的方法要在很多地方都使用到的时候建议使用单例。  单例的3个步骤,也是判断是否是单例的依据 1 就是

    2024年02月05日
    浏览(28)
  • 单例模式(C++)

    保证一个类仅有一个实例,并提供一个该实例的全局访问点。 在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性、以及良好的效率。 如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例? 这应该是类设

    2024年02月13日
    浏览(29)
  • 【C++】—— 单例模式详解

    前言: 本期,我将要讲解的是有关C++中常见的设计模式之单例模式的相关知识!! 目录 (一)设计模式的六⼤原则 (二)设计模式的分类 (三)单例模式 1、定义  2、实现方式 1️⃣ 懒汉模式  2️⃣ 饿汉模式 (四)懒汉模式的安全实现 总结 首先我们需要知道的是设计

    2024年02月09日
    浏览(30)
  • 单例模式——C++版本

    在一个项目中,全局范围内,某个类的实例有且仅有一个,通过这个唯一实例向其他模块提供数据的全局访问,这种模式就叫单例模式。 类中多对象的操作函数有如下几个: 构造函数 : 能够创建出一个新对象; 拷贝构造函数 :能够根据一个已经存在的对象拷贝出一个新对

    2024年02月09日
    浏览(35)
  • c++——单例模式

    单例模式确保一个类只有一个实例,并提供一个全局访问点以获取该实例。这通常通过让类的构造函数为私有,以防止外部直接实例化,然后提供一个静态方法来获取实例。 实现单例模式的主要步骤包括: ①将类的构造函数和拷贝构造函数声明为私有,以防止外部直接实例

    2024年02月12日
    浏览(32)
  • C++单例模式

    1.什么是单例模式 单例模式是指在整个系统生命周期内,保证一个类只能产生一个实例,确保该类的唯一性。 2.单例模式分类 单例模式可以分为 懒汉式 和 饿汉式 ,两者之间的区别在于创建实例的时间不同。 懒汉式 系统运行中,实例并不存在,只有当需要使用该实例时,才

    2024年02月05日
    浏览(35)
  • C++学习—单例模式

    目录 ​编辑 一,单例模式介绍 二,单例模式下的两种模式  1,饿汉模式 2,懒汉模式   单例:在全局只有一份实例。 单例模式是编程的经典模式之一。 二,单例模式下的两种模式  1,饿汉模式 饿汉模式:在main函数启动前就先把实例化的类对象准备好。 1,提前准备好实

    2024年02月19日
    浏览(32)
  • C++之单例模式

    单例模式(Singleton Pattern)是 面向对象中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式

    2024年01月23日
    浏览(56)
  • C++ 【单例模式】

    简单介绍 单例模式是一种 创建型设计模式 | 让你能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点。 它也会破坏代码的模块化特性,因为单例模式往往会 承担了很多的职责 ,导致与 其他模块 产生过多的耦合 基础理解 单一职责原则: 一个类或模块应该只有

    2024年04月12日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包