无论是太阳下,还是风雨中,都要成长!
前面对C++的Singleton模式的探讨还都是针对通过静态变量来创建对象。但学习嘛,多走点总不是坏事。
接下来就来看看通过 new 来创建单件对象的单件类设计。既然是用 new 来创建了,那自然就不能忽略需要用 delete 来释放。
好了,先来看看代码:
[单件类的线程安全性]
代码中,类A和C都是单件类,且都是通过 new 来分配和创建单件对象,在对象的释放上,也统一的使用Release函数封装了delete操作,并手动调用。但A的单件和C的单件又是不同的,这个不同就在于 A 是通过将 new 出来的对象指针赋给成员变量,而 C 则将 new 出来的对象指针给了局部静态变量。可别小看了这个区别哦!!就因为这一不同,结果 A 不是线程安全的,而 C 却是线程安全的。当然,也可以通过使用临界区、互斥量等来是 A 变为线程安全,可是,该在什么时候去初始化临界区或创建互斥量对象等呢?以临界区为例,按常规的在 main 的头部进行临界区的初始化,末尾则进行临界区的删除;但是很不幸,程序崩溃了!!因为全局变量在构造是调用了单件A,而单件A创建用到了临界区,可这是临界区却还没有初始化。那么将这临界区的初始化放到A的构造呢?一样使用先去初始化。放到A::GetInstance()内呢?影响效率,且存在重复初始化。
放到B的构造呢?还是被反复多次初始化了……。而且,有非B类的更先构造并调用了单件A的全局对象呢?!
——看来,从线程安全考虑,单件类A的设计应当被否决了。
[单件类对象的释放]
撇开线程安全问题不看,就上面的Demo,我们将会发现另一个严重问题——何时才能调用A和C的Release方法,释放A和C的单件对象呢?如果,是如Demo中那样,在main函数末尾进行释放,那么因为类B的几个全局对象的析构,将发生如下的糟糕结果:
但是,如果我们把Release放入B的析构中,则A将被多次的分配和释放,而C则被多次调用析构。无奈咯,考虑释放的困难,这里的A和C的单件类设计方式看来也都还是否决的好!~
posted on 2012-03-13 00:55 青碧竹 阅读(240) 评论(0) 编辑 收藏 引用 所属分类: 设计模式
Powered by: C++博客 Copyright © 青碧竹