也谈单件模式类的设计(C++)
来源:互联网 发布:北大青鸟学编程 编辑:程序博客网 时间:2024/05/17 05:56
单件模式在设计模式中是比较基本的模式之一,它是用来构造在整个应用中只有唯一实例的对象。今天在CODE的过程中采用单件模式实现了一个类,大至如下:
class Device: public BaseDevice
{
private:
int m_port;
...
private:
Device();
Device& operator=(const Device&);
static Device* _instance;
...
public:
DWORD Initialize();
~Device();
public:
static Device* Instance();
};
Device *Device::_instance = NULL;
Device::Device()
{ ... }
Device::~Device()
{ }
DWORD Device::Initialize()
{ ... }
Device* Device::Instance()
{
if(NULL==_instance)
{
_instance=new Device();
}
return _instance;
}
这样一个简单的单件实例类就实现好了,那么它的实例在应用过程中就是唯一的了吗?当然是的。单件模式要实现目标就是这样。但我在编程过程中遇到了一个问题——上面的代码存在着BUG:当对单件对象delete后然后再获取实例并调用其的方法时出现访问地址错误?
Device*dv=Device::Instance();
if(dv)
dv->Initialize();
...
delete dv;
dv=NULL;
...
dv=Device::Instance();
if(dv)
dv->Initialize(); //在这里调用出错
如果只看这段代码很难察觉到错误,因为这些都是正常的。DEBUG了半天才找到了错误的根源——错误还是出在单件类的设计和实现上。为了使对象的实例唯一,我们使类的构造函数私有,公开类静态成员函数获得实例,对象的实例保存在类的静态成员变量中。客户端每次调用Instance返回的是这个静态成员变量。那为什么在delete之后重新获得实例却出现访问地址错误呢,明明看到第二个dv指针不是NULL值啊?问题就出在析构函数那:没有对静态变量_instance=NULL。因为在执行delete操作时,其实对象的实例已经得到释放了,只是这时的_instance指针没有赋NULL值,依然指向最初创建对象的那个地址!这就是所谓的“野指针”吧。
Device::~Device()
{
Device::_instance=NULL;
}
更进一步的想,在单件模式的设计应该也分几种情况。像上面那种方式,实例是唯一,但可以被应用端随时释放并再创建,另一种我想是把析构函数也私有化,这样应用端就不能释放,但是怎么创建呢?这就需要配合其它的设计模式吧,比如抽象工厂,专门负责对象的创建和释放。
- 也谈单件模式类的设计(C++)
- 单例模式的设计(C++)
- 设计模式(C++)
- 设计模式的实现(C++)------工厂方法模式(FactoryMethod)
- 设计模式的实现(C++)------抽象工厂模式(AbstractFactory)
- 设计模式 - 线程安全的单例模式(C#)
- 设计模式--代理模式的简单实现(C#)+类关系图
- Singleton设计模式(C++)
- Observer设计模式(C++)
- Template设计模式(C++)
- 设计模式--观察者模式(C++)
- 设计模式--观察者模式(C++)
- 设计模式C++(Strategy策略模式)
- 设计模式 - 简单工厂模式(C++)
- 设计模式--观察者模式(C++)
- 设计模式C++(Strategy策略模式)
- 设计模式 command模式 (c++)
- 设计模式之状态模式(c++)
- 附录 匈牙利命名法
- ACCESS如何随机抽取数据
- 一次关于旨在降低编译时间的整改工作(vc++)
- 冰人来源
- Db2/SQL命令大全
- 也谈单件模式类的设计(C++)
- C/C++ 常见误区
- google的影响力
- #pragma的使用(引用)
- 为中国本土IT原创喝彩,孙卫琴老师新书《Java面向对象编程》新书发布会实录
- 书到用时方恨少
- putty中文显示
- 想创建一个QQ群
- org.apache.jasper.JasperException