C++Singleton(坚持更新c++内容的第23天)

概念

Singleton是对全局变量的取代策略。

作用: 保证一个类只能有一个实例,并提供一个全局唯一的访问点。

仅有一个实例:通过类的静态成员变量来体现。 

提供访问它的全局访问点:访问静态成员变量的静态成员函数来体现。

设计模式一书中给出一种很不错的实现,定义一个单例类,使用类的私有静态指针变量指向类的唯一实例,并用一个公有的静态方法获取该实例。

单例模式通过类本身来管理其唯一实例,这种特性提供了解决问题的方法。唯一的实例是类的一个普通对象,但设计这个类时,让它只能创建一个实例并提供对此实例的全局访问。唯一的实例类Singleton在静态成员函数中隐藏创建实例的操作。习惯上把这个成员函数叫做Instance(),它的返回值是唯一实例的指针。

单例类Singleton有以下特征:

它有一个指向唯一实例的静态指针,并且是私有的;

它有一个公有的函数,可以获取这个唯一的实例,并且在需要的时候创建该实例;

它的构造函数是私有的,这样就不能从别处创建该类的实例。

UML图:

 在Singleton模式的结构图中可以看到,我们通过维护一个static的成员变量_instance来记录这个唯一的对象实例。通过提供一个staitc的接口Instance来获得这个唯一的实例。

代码如下:

Singleton.h

Singleton.cpp

 

 test.cpp

运行结果:

 Singleton不可以被实例化,因此我们将其构造函数声明为protected或者直接声明为private。

 ---

程序设计过程中,经常会有"只能创建一个实例"的需求。

为保证创建单一实例,必须确保程序中只调用new Class()

由于随着代码的复杂性的增加,对象单例性经常会被忽视,由于资源独占性等原因,经常会产生一些意想不到的问题。

为了更好地实现优美的代码设计,单例模式(Singleton)应运而生。

单例模式的定义是:保证一个类、只有一个实例存在,同时提供能对该实例加以访问的全局访问方法。单例模式是一种对象创建型模式,使用单例模式,可以保证为一个类只生成唯一的实例对象。也就是说,在整个程序空间中,该类只存在一个实例对象。

 在 Singleton 模式的结构图中可以看到,我们通过维护一个 static 的成员变量来记录这个唯一的对象实例。

 应用场景

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

在多个线程之间,比如初始化一个socket资源;

在整个程序空间使用全局变量,共享资源;

大规模系统中,为了性能考虑,需要节省对象的创建时间等等。

使用方法:

a. 构造函数私有化(设置为private)=》防止从类外调用构造函数,保证在任何情况下只生成一个实例;

b. 提供一个全局的静态方法GetInstance(全局访问点)=》便于提供从类外部获取单例类的唯一实例的方法;

c. 在类中定义一个静态指针,指向本类的变量的静态变量指针。

懒汉单例和饿汉单例多线程场景分析

1."懒汉"模式虽然有优点,但是每次调用GetInstance()静态方法时,必须判断NULL == m_instance,使程序相对开销增大;

2. 多线程中会导致多个实例的产生,从而导致运行代码不正确以及内存的泄露;

3.未提供释放资源的函数,存在内存泄漏问题。

由于C++中构造函数并不是线程安全的。C++中的构造函数简单来说分两步:

第一步:内存分配;

第二步:初始化成员变量;

由于多线程的关系,可能当我们在分配内存好了以后,还没来得急初始化成员变量,就进行线程切换,另外一个线程拿到所有权后,由于内存已经分配了,但是变量初始化还没进行,因此获取成员变量的相关值会发生不一致现象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值