跟我学C++中级篇——单实例和静态化

235 篇文章 94 订阅

一、单实例模式

在设计模式中,单实例模式几乎是所有语言中都非常常用的一种设计模式。它在实际的应用中也非常广泛,在很多的开源框架中,都可以看到单实例的影子。单实例,简单的就可以看做在整个应用周期中,只有一个对象的变量。其好处其实就一点,可以集中控制对对象的各种处理(比如优化、内存管理等等),缺点其实就是两个,一个是生命周期无法动态控制;另外一个就是无法动态伸缩。前者容易理解,后者举个简单例子,如果想同时连接多个数据库,这就不好控制了。

二、静态方法和静态变量

学习C/C++语言的,对静态变量和静态方法都是很熟悉的。静态化和单实例也有着千丝万缕的关系,在实现单实例的发展过程中,有很多种方式,现在比较常见的基本就是两种,一种是使用函数的局部静态变量,一种是使用std::call_once,而且这两个都需要从C++0x开始支持。
首先说明一点,此处不是分析如何实现单实例,所以不会对实现的各种方式进行分析说明,重点在于单实例与静态化的关系这一点进行深入剖析。为什么单实例中对静态化情有独钟呢?可不可以全部使用静态化来实现单实例呢?
答案其实反复回答过,静态变量可以防止反复检测(比如经典的Double Check)的性能损失(函数的局部静态变量仍然会有一个检测过程,性能仍然会有些损失),至于能不能使用全部静态化来实现单实例,当然是没有问题的。但问题在于,使用这种方式,会丧失一定的灵活性,这个在下面分进行分析。

三、单实例中的静态化

那么单实例中使用静态化操作有什么优势呢?
1、线程安全性
熟悉全局和静态变量的开发者都有一个头疼的地方,编译器是无法保证多个文件内的相关这样的变量的初始化顺序的。这就出现一个非常难受的问题,如果以后扩展需要多个文件(或者多个库)内的全局或者静态变量需要互相依赖,有可能会出一些让人想象不到的问题。有大牛提出过,把全局或者静态变量搞到一个文件中,可实际场景中,算法保密甚至第三方库都使开发者无法达到这样的目的。
而Meyers’ Singleton即Scott Meyers最早提出来的C++单例模式的写法,其实就是局部静态变量的方式来实现,不过在前面也提到了,它需要C++0x做保证,同样,在一些编译器上,可能也有一些具体的问题,但这不是讨论的范畴了。
2、接口继承
如果使用单实例封装使用静态化,那么就可以实现继承来延续静态化的应用。这其实是一个非常重要的应用,可以继承,意味着可扩展性极大的增强,即灵活性的增加。

3、延迟加载
所谓延迟加载,其实就是懒汉模式,它只会在第一次用到时创建这个对象。这在一些资源要求严格的场景下,还是很有用处的。
4、解决了多文件(库)的互相引用问题
其实这点还是静态变量的初始化顺序导致的问题,这个非常重要,可能很多人都没遇到过,但经验表明,一旦出现这个问题,简直就是一场灾难,因为正常的思维情况下很少考虑这种情况。当你弄明白是这个原因后,会陷入无比的自责和自馁中。

5、生命周期
单实例封装静化,可以主动控制生命周期,这与使用一个单纯的静态或者全局变量有着可控的优势。毕竟全局(静态)变量一旦生成,就是整个进程的生命周期陪伴着,这对于一些对资源要求苛刻的场景下,还是很在裨益的。

另外,单实例的参数传递(非常大的应用程序中)以及后期对测试的支持,都可以做为一种优势来进行说明。但重点是静态化使用与单实例中,如何最具有优势,这才是开发者需要首先考虑的。

下面给出一个Meyers’ Singleton例子:

struct Singleton
{

  static Singleton &instance()
  {
    static Singleton s;
    return s;
  } // instance

  Singleton(const Singleton &) = delete;
  Singleton & operator = (const Singleton &) = delete;

private:

  Singleton() {}
  ~Singleton() {}

}; // struct Singleton
struct OwnerSingleton:public Singleton
{};

不过一般来说,可能对绝大多数程序员来说,实际情况中遇到单例继承的情况极为罕见吧。
其实直接使用全局或者静态变量与使用单实例,从开发的本质来说,区别不大,但单实例更好的解决了在上层逻辑上的灵活扩展性,这其实就是设计的意义,也是设计模式的意义。实现功能可能大家都会,可如何做得更好,就见仁见智了。

四、总结

到最后,总结各种经验其实可以发现,在实际的应用场景上,使用一些习惯用法或者说设计模式的目的,主要是为了扩展性和防御性编程。如果能够明确的知道不会发生或者某些异常会被阻止的情况下,不进行使用其实也是没问题的(话只能说到这儿,大家自己考虑)。说这些话的目的就是,经验是个好东西,但不要陷入经验主义,书本是个好东西,不要陷入本本主义。实践是检验真理的唯一标准,抓住老鼠的一定是好猫。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值