C++设计模式---单例模式

目录

为什么需要设计模式

什么是单例模式?

饿汉式:

线程安全的懒汉式单例模式方法1:

线程安全的懒汉式单例模式方法2:


为什么需要设计模式

简单来说,设计模式就是在解决某一类问题时,有既定的优秀的代码框架可以用,优点如下:

  1. 代码易于维护;
  2. 能够做到软件设计的开-闭原则(对修改关闭,对扩展开放);
  3. 合理的设计模式,能够做到软件设计的高内聚,低耦合。

什么是单例模式?

单例模式指的是,你无论怎么获取,永远只能得到该类的一个实例对象,所以单例模式的设计有如下三步曲:

  1. 构造函数私有化,去除拷贝构造和赋值重载;
  2. 提供一个私有的静态实例对象(饿汉式)或者静态对象指针(懒汉式);
  3. 提供一个对外的静态的成员方法,获取该对象。

首先区别两个概念:饿汉式单例模式与懒汉式单例模式(根据对象的创建时机不同来区分):

  1. 如果在使用对象之前,对象就已经创建好了,则称为饿汉式;
  2. 如果在使用对象之时,我们才开始创建对象,则成为懒汉式。

什么是线程安全?

既然是线程安全问题,那么毫无疑问,所有的隐患都是在多个线程访问的情况下产生的,也就是我们要确保在多条线程访问的时候,我们的程序还能按照我们预期的行为去执行;具体在单例模式中(懒汉式)的表现就是:在多线程并发环境下,我们要确保只有一个线程会创建类的实例对象,其它线程基于这个对象进行操作,而不会再去创建实例。懒汉式如果不加以措施的话默认是线程不安全的,饿汉式由于对象在使用之前就已经创建好了,所以是线程安全的。

饿汉式:

//饿汉式
//不用考虑线程安全问题,在程序启动的时候就已经调用构造函数开辟空间实例化对象了
class Singleton
{
    public:
     /*3.获取类的唯一实例对象的接口方法*/
        static Singleton* getInstance() //静态的成员方法,访问私有的静态成员数据
        {
            return &instance;
        }


    private:
        /*2.定义一个唯一的类的实例对象*/   
        static Singleton instance; //私有的静态成员数据,只能类内访问,类外无法引用
        /*1.构造函数私有化*/
        Singleton()
        {

        }
        //去掉拷贝构造和赋值重载
        Singleton(const Singleton&) = delete;
        Singleton& operator=(const Singleton&) = delete;
};
Singleton Singleton::instance;  // 静态变量,类内声明,类外定义

针对以上代码,回答一些问题:

(1)为什么构造函数私有化,去除拷贝构造和赋值重载?

        这样保证了我们外部是无法随意创建对象的。

(2)为什么是静态实例和静态方法?

        首先我们要知道,类外调用类中的成员方法有两种方式:

  1. 创建一个该类的对象,通过对象调用;
  2. 通过类名加作用域::来调用(类中方法必须是静态的)。

        由于构造函数私有化,我们无法获得类的一个实例,所以通过第一种方式显然不行,那么只能通过第二种方式,将成员方法定义为静态的,而由于静态的成员方法只能访问静态的成员数据,所以提供的对象实例也要设置为静态的。

        注意:对类的静态成员数据,要类内声明,在类外进行定义。

线程安全的懒汉式单例模式方法1:

std::mutex mtx;
//懒汉式  线程安全方式1
class Singleton
{
    public:
     /*3.获取类的唯一实例对象的接口方法*/
     // 是不是可重入函数呢?不是           锁+双重判断---->线程安全的懒汉式单例模式
        static Singleton* getInstance() //静态的成员方法,访问私有的静态成员数据
        {
            //lock_guard<std::mutex> guard(mtx);  //锁的粒度太大了
            if(instance == nullptr)
            {
               lock_guard<std::mutex> guard(mtx); //锁放这,减小粒度
                if(instance == nullptr)
                {
                      /*                 非原子操作
                        开辟内存
                        构造函数
                        给instance赋值
                      */
                    instance = new Singleton();
                }
            }
            return instance;
        }

    private:
        /*2.定义一个唯一的类的实例对象指针*/   
        static Singleton *volatile instance; //私有的静态成员数据,只能类内访问,类外无法引用
        /*1.构造函数私有化*/
        Singleton()
        {

        }
        //去掉拷贝构造和赋值重载
        Singleton(const Singleton&) = delete;
        Singleton& operator=(const Singleton&) = delete;
};
Singleton *volatile Singleton::instance = nullptr;  // 静态变量,类内声明,类外定义

步骤:构造函数私有化,去除拷贝构造和赋值重载;提供一个静态的指向实例对象的指针;提供一个静态的成员方法,在该方法里面实例化对象。

注意:上面用到了volatile关键字,保证了对volatile修饰的变量编译器不会进行优化,否则我们在执行new操作时可能由于编译的优化,代码逻辑不会按照我们预期的执行。其次volatile还有一个作用:可见性,对volatile修饰的变量的操作是直接在主存上操作的,是不经过高速缓存与寄存器的,所以一个线程对其进行操作之后,其余线程保证能立刻感受到其变化。

线程安全的懒汉式单例模式方法2:

//懒汉式  线程安全方式2
class Singleton
{
    public:
        //线程安全精简的懒汉单例模式
        static Singleton* getInstance() //静态的成员方法,访问私有的静态成员数据
        {
            static Singleton  instance; //函数内部的一个静态局部变量,程序启动阶段内存就分配好了,在数据段
                                        //静态对象的初始化是在程序第一次运行到它的时候才初始化
                                        //函数静态局部变量的初始化,在汇编指令上已经自动添加互斥指令了
                                        //不用担心线程安全的问题
            return &instance;
        }

    private:   
        
        /*1.构造函数私有化*/
        Singleton()
        {
            //很多初始化的代码
        }
        //去掉拷贝构造和赋值重载
        Singleton(const Singleton&) = delete;
        Singleton& operator=(const Singleton&) = delete;
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
设计模式是在软件开发中常用的一种编程思想,它提供了一种解决问题的方法论,可以帮助开发者更加灵活和高效地开发软件。基于qt4开源跨平台开发框架的PDF设计模式主要包括以下几个方面。 首先,观察者模式是一种常用的设计模式,它可以用于实现PDF文件的订阅和通知功能。通过该模式,用户可以选择关注自己感兴趣的PDF文件,并在文件更新时接收到通知。 其次,工厂模式是常用的创建型设计模式,它可以帮助开发者根据需要创建不同类型的PDF文件。例如,可以使用工厂模式创建基本的PDF文件、加密的PDF文件或者带有水印的PDF文件。 再次,装饰器模式是一种结构型设计模式,可以用于在不修改现有代码的情况下为PDF文件添加额外的功能。开发者可以通过装饰器模式为PDF文件添加页眉、页脚、书签等功能,同时保持原有的PDF文件结构和功能不受影响。 此外,策略模式也是常用的设计模式之一,在PDF开发中可以用于实现不同的压缩策略和加密策略。通过策略模式,开发者可以根据需求选择不同的策略来实现对PDF文件的处理和管理。 最后,单例模式是一种创建型设计模式,可以确保在整个应用程序中只有一个PDF文件实例。通过单例模式,可以在不同的模块中共享同一个PDF文件对象,避免资源浪费和数据冲突。 总而言之,设计模式在基于qt4开源跨平台开发框架的PDF开发中具有重要的作用。以上提到的几种设计模式可以帮助开发者更好地组织和管理PDF文件,提高开发效率和代码的可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值