单例模式

单例模式是一种对象创建模式,使用单例模式,可以保证为一个类生成唯一的实例对象。也就是说在这个程序空间该类只有一个实例对象。

GoF对单例的定义:保证一个类、只有一个实例存在,同时提供对该实例加以访问的全局访问方法。

单例模式UML

单例模式的目的就是保证一个类只有一个实例,并提供一个访问它的全局访问点。

使用单例模式的原因

在应用系统开发中,我们常常有以下需求:

  • 多个线程公用一个socket资源,或者操作同一个对象
  • 在整个程序空间需要使用全局变量,共享资源
  • 大规模系统中,为了性能考虑,需要节省对象创建的时间等

实现步骤:

  1. 构造函数私有化
  2. 提供一个全局的静态方法(全局访问点)
  3. 在类中定义一个静态指针,指向本类的变量的静态变量指针

构造函数私有化的作用:构造函数私有化之后,则构造该类的对象,必须在类内部完成。

懒汉式单例模式

叫懒汉式的原因,是因为只有再用的时候才会创建类中的全局指针。

代码实现如下:

#include <iostream>using namespace std;class Singleton
{private:Singleton(){cout << "sluggard singleton construct start." << endl;}public:static Singleton *getInstance(void){if(NULL == m_psl) // 懒汉式,每次获取实例都要判断,在多线程中会存在问题{m_psl = new Singleton;}return m_psl;}static void FreeInstance(){if(NULL != m_psl){delete m_psl;m_psl = NULL;}}
private:static Singleton *m_psl;
};// 静态变量初始化的方法,要放到类的外面
Singleton *Singleton::m_psl = NULL;// 懒汉式,只有在使用的时候才会去创建
// 存在的问题,多个线程同时首次调用时,可能会出现创建多次的问题(导致内存泄漏)int main(int argc, char const *argv[])
{// 使用功能去全局获取接口获取资源Singleton *p1 = Singleton::getInstance(); Singleton *p2 = Singleton::getInstance();if(p1 == p2){cout << "p1 equal p2" << endl;}else{cout << "p1 not equal p2" << endl;}// 手动释放单例模式创建的唯一一个对象Singleton::FreeInstance();cout << "singleton." <<  endl;return 0;
}

编译之后输出结果:

sluggard singleton construct start.
p1 equal p2
singleton.

饿汉式

饿汉式,与懒汉式唯一的差别就是创建方式上,懒汉式是在首次调用的时候才创建,饿汉式是不管是否调用,在静态指针初始化的时候就创建指针指向的对象。

#include <iostream>using namespace std;class Singleton
{private:Singleton(){cout << "sluggard singleton construct start." << endl;}public:static Singleton *getInstance(void){return m_psl;}static void FreeInstance(){if(NULL != m_psl){delete m_psl;m_psl = NULL;}}
private:static Singleton *m_psl;
};// 静态变量初始化的方法,要放到类的外面
// 饿汉式是在初始化指变量的时候就对其进行创建,不管是否被调用
Singleton *Singleton::m_psl = new Singleton;int main(int argc, char const *argv[])
{// 使用功能去全局获取接口获取资源Singleton *p1 = Singleton::getInstance(); Singleton *p2 = Singleton::getInstance();if(p1 == p2){cout << "p1 equal p2" << endl;}else{cout << "p1 not equal p2" << endl;}// 手动释放单例模式创建的唯一一个对象Singleton::FreeInstance();cout << "singleton." <<  endl;return 0;
}

饿汉式执行之后输出结果:

sluggard singleton construct start.
p1 equal p2
hungry singleton.

两者分析:

懒汉式因为使用的时候才会创建内存,所以当多个线程同时使用的时候可能会出现多次创建的问题,饿汉式不存在这个问题。

懒汉式虽然有有点,但是每次调用GetInstance()静态方法都必须判断静态指针是否为NULL使程序相对开销增大,多喜爱能成中会导致多个实例产生,从而导致运行代码不正确以及内存泄漏,也有可能是多次释放资源。

这是因为C++中构造函数并不是线程安全的,C++中的构造函数简单分为两步

  1. 内存分配
  2. 初始化成员变量

由于多线程的关系,可能内存放分配好,还没有给成员赋值,就发生了线程切换,导致下个线程中又申请了一遍内存。

23种设计模式C++源码与UML实现--单例模式中的饿汉模式和懒汉模式相关推荐

  1. 23种设计模式C++源码与UML实现--外观模式

    外观模式 facade模式也叫外观模式,是由GoF提出的23种设计模式中的一种,facade模式为一组具有类似功能的类群,比如类库,子系统等等,提供一个一致的简单界面.这个一致的简单的界面被称为fac ...

  2. 23种设计模式C++源码与UML实现--建造者模式

    建造者模式 代码仓库地址:建造者模式 Builder模式也叫建造者模式或者生成器模式,是由GoF提出的23种设计模式中的一种.Builder模式是一种对象创建模式之一,用来隐藏复合对象的创建过程.他把 ...

  3. 23种设计模式C++源码与UML实现--命令模式

    命令模式 Command模式也叫命令模式,是行为设计模式的一种.Command模式通过被称为Command的类封装了对目标对象的调用行为以及调用参数. 在面向对象的程序设计中,一个对象调用另外一个对象 ...

  4. 23种设计模式C++源码与UML实现--迭代器模式

    迭代器模式 Iterator模式也叫迭代模式,是行为模式之一,他把对容器种包含的内部对象的访问委让给外部类,使用Iterator按顺序进行遍历访问的设计模式. 在使用Iterator模式之前,首先应该 ...

  5. 23种设计模式C++源码与UML实现--状态模式

    状态模式 State模式也叫状态模式,是行为模式的一种,State模式允许通过改变对象的内部状态而改变对象的行为,这个对象变现的好像修改了它的类一样. 状态模式主要解决的事当控制一个对象状态的条件表达 ...

  6. 23种设计模式C++源码与UML实现--观察者模式

    观察者模式 Observer模式是行为模式之一,它的作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态. Observer模式提供给关联对象一种同步通信的手段,使得某个对象与 ...

  7. 23种设计模式C++源码与UML实现--策略模式

    策略模式 Strategy模式也叫策略模式,是行为模式之一,它对一系列的算法加以封装,为所有算法定义一个抽象算法接口,并通过继承该抽象算法接口对所有的算法加以封装和实现,具体的算法选择交给客户端决定. ...

  8. 23种设计模式C++源码与UML实现--工厂模式

    工厂模式 工厂方法模式同样属于类的创建型模式,又被称为多态工厂模式.工厂方法的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中. 核心工厂类不在负责产品的创建,这样核心类成为一个抽象 ...

  9. 23种设计模式C++源码与UML实现--原型模式

    原型模式 一个复杂对象,具有自我复制功能,统一一套接口. 原型模式主要面对的问题是:某些结构复杂的对象的创建工作,由于需求的变化,这些对象进场面对着剧烈的变化,但是他们却拥有比较一致的接口. 原型模式 ...

最新文章

  1. 75. Find Peak Element 【medium】
  2. HDU 5411 CRB and Puzzle (2015年多校比赛第10场)
  3. nagios errors
  4. 变态一把,从internet获取所有手机号以及所在地
  5. 给oim_对OIM Web(UI)层进行压力测试
  6. Control-Tree
  7. 【数据库系统工程师】数据库系统工程师考情分析
  8. 西门子界面官方精美触摸屏+WINCC程序模板 西门子官方触摸屏程序模板,炫酷的扁平式动画效果
  9. java计算机毕业设计O2O生鲜果蔬电商设计与实现(附源码、数据库)
  10. 简单实现图片转彩色字符画
  11. 开调查公司创业,他的公司营业额达80万
  12. opencv的dct和scipy.fftpack里dct的区别
  13. 怎么把一个PDF文件拆分成多个?
  14. 购车指南首次买车必看系列之(二): 产权篇
  15. 电脑开机后显示器会出现无视频输入然后出现睡眠模式 最近几天会出现显示器打开就出来无视频输入?
  16. android模仿ios滚动,模仿iOS版微信的滑动View效果
  17. 腾讯企业邮箱使用简单说明
  18. 基于java安防管理平台计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署
  19. 为什么人人都应该玩儿点儿DIY?
  20. The Bucket List 题解

热门文章

  1. hdu 4529(状态dp)
  2. poj-2101Honey and Milk Land
  3. Anchor free Detector:FCOS
  4. LeetCode 21. 合并两个有序链表(Merge Two Sorted Lists)
  5. 将web项目导入到eclipse/MyEclipse中常见错误
  6. java 对字符串中的数值排序
  7. Selenium 自动化测试之道--Maven-TestNG
  8. android设置系统横屏方案
  9. 【原创】 关于全局静态变量初始化
  10. testng提供的Assert类断言使用