【C++设计模式】十 一、单例模式

一、单例模式的概念

(一)基础概念

【1. 概念】

单例模式Singleton:单个对象的模式。目的:类只能实例化一个对象

【2. 单例模式的分类】

  • 懒汉模式延时加载,唯一对象使用时才加载
  • 饿汉模式贪婪加载,在类加载时就生成唯一的对象,线程安全的单例模式。

【3. 饿汉模式的特点:】

优点:

  • 线程安全; 在产生线程之前就完成唯一对象的创建,所以不会存在线程不安全问题。
  • 运行时获取对象速度快;因为在类加载时已经创建,运行只用获取即可。

缺点:

  • 存在资源浪费的可能;如果不需要生成唯一的对象,只是加载了该类,还是会创建一个对象,资源效率不高。
  • 类加载时速度慢;需要创建对象。

【4. 懒汉模式的特点:】

优点:

  • 资源利用率高;只有调用该类的公有接口时才会创建唯一的对象。
  • 加载类速度快。

缺点:

  • 存在线程安全问题,需要引入同步机制;如果程序在多线程情况运行,创建唯一对象的操作不是原子操作,所以就存在临界资源被多个线程访问抢占的情况出现,导致线程不安全问题,所以需要引入同步机制,如互斥锁,信号量等来控制唯一对象的生成。
  • 运行获取速度慢, 多线程同步机制带来额外开销。

所以建议使用饿汉模式,可以减少额外的同步开销。

(二)单例模式的设计思想

【 一、思想切入点:】

需要生成唯一的对象,故了解如何生成一个对象,然后对其进行控制,达到只创建一个对象的目的。

对象的生成需要两步:

  • 开辟对象所占的内存空间—系统开辟,我们无法控制
  • 调用构造函数—自己写的,所以要只生成一个对象,可以对其进行控制。
  • 拷贝构造函数也可以生成对象,那么也要对它进行控制。

【二、 根据切入点,进行具体函数设计】

【1. 将生成对象的接口屏蔽】

  1. 对构造函数进行控制:如果构造函数访问限定符为公有的,那么任意位置都可以访问,就代表任意位置调用构造函数生成对象,无法控制对象的个数。所以第一步就是屏蔽对象生成的接口,将其写为私有的,只能在本类类中访问,在类外无法调用。无法生成对象,那么就可以控制对象生成的个数。构造函数内部就实现对成员变量的初始化即可
  2. 对拷贝构造函数进行控制,将其也写为私有,但是不需要进行具体的实现,因为调用拷贝构造的作用是,用已有的对象生成一个新对象。要生成唯一的一个对象,肯定不能调用它,所以只需将它声明为私有的,告诉编译器这个是私有的,不可以用。

【2. 提供接口在类中生成唯一对象】

类外无法调用,那么我们只要在类中生成唯一的对象,然后供外部使用即可。所以我们在类中提供一个接口,然后返回出去供外部使用。通过这个接口得到对象,进行使用

【2-1 函数返回值设计】

需要返回一个对象,无非就三种情况:

  • 类名:所有类类型的返回值都是由临时对象带出的,那么就存在临时对象,现在就有两个对象,一个生成的,一个临时对象,和设计原则不符,错误。
  • 类名&:无临时对象生成
  • 类名*:无临时对象生成

所以返回值可以使用指针或引用。

【2-2 函数修饰关键字的考虑–从如何调用的角度入手】

如何调用这个公有的成员方法来生成唯一的对象?

如果依赖对象调用,那么需要通过对象调用接口,但是调用它了才会生成对象,形成了一种相互依赖关系,那么这第一个对象要如何生成呢?这就和鸡生蛋,蛋生鸡的问题一样了。所以如果依赖对象调用,那么第一个对象永远无法生成。

所以必须将此函数设计为不依赖对象调用,那么就需要将此函数写为静态函数,不依赖对象调度,通过类作用域就可以调用。所以当一个接口目的是为了生成对象,一般都写为静态的。

【3. 标识唯一的对象】

为了防止这个公有的接口被调用多次,需要定义一个标识唯一对象的指针, 这个指针不属于对象,不依赖对象调动,只能让本类中的接口函数调动,故将其还是定义为静态变量,在类外进行初始化,初始化为NULL。

  • 只要为空,就表示唯一的对象还没有生成,允许调用构造函数生成对象。
  • 如果不为空,那么就直接返回这个对象的地址即可。

总结单例模式设计点就三大点:

  1. 屏蔽生成对象的接口;构造函数,拷贝构造函数访问限定符为私有private。
  2. 通过接口来生成唯一的对象;不能以类类型返回,用static关键字修饰。
  3. 定义指针指向唯一的对象,用来标识唯一的对象。

二、单例模式之懒汉模式

(一)线程不安全的懒汉模式

根据单例模式的设计思路,我们可以写出懒汉模式的单例模式:

在公有的成员方法中调用构造函数生成对象,这样只有调用公有接口才会生成对象。那么代码如下:

# include<iostream>
/*
//1.懒汉模式*/
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值