单例 模式(上)
单例模式(上)
- 实际生活中的单例需求
- 超市收银机中的扫描枪,在面向对象的设计中,最好设计单例模式,因为一个收银终端只需要一个扫描枪来工作.如果是两个或者多个,多出来的扫描枪,对收银员来说是无用的,她在实际工作中用不上.
- 设计类的思考
- 需要控制类的对象数目(1个)
- 要达到上条需求,必须对外隐藏构造函数,隐藏拷贝构造,隐藏拷贝赋值.在外部完全没有办法创建这个类的对象,此时外面没有办法使用这个类.
- 利用一个返回静态对象的公有的函数,来new一个静态对象.
- 最后是,设计这个唯一对外的函数,控制外部只能使用一个,唯一的对象.
- 细化代码思路
- 将构造函数的属性设置为private
- 将所有拷贝系的函数:拷贝构造和拷贝赋值设置为private
- 定义类型的static 标记 instance并初始化为Null
- 当需要使用对象时,先访问静态标记 instance的值
- 如果保证它是独一份的,创建出来后,它不可以再被创建呢?
- 做一个判断,如果静态标记instance是空的,则创建一个instance对象,因为new了对象,并且返回了这个静态对象,所以instance此时非空.
- 如果instance不为空,则返回类的对象
- 把拷贝系的函数:拷贝构造与拷贝赋值都设计为private
- 使用一个public的方法GetInstance(),返回一个静态的对象.
- 代码进行中的注意点
- instance实例类型应该为该单例类的* 如: type * instance
- static 修饰的对象,要在类外面申明
- 类外面申明时,要注意"模板构造类型 类型构造对象"的规范书写,不要忘记了域作用符::
- 拷贝构造是不需要的,就设计为private
- 拷贝赋值也是不需要的,也应该设计为private
- 最后在类外部实现GetInstance函数,先判断是否为空,如果这空则new一个对象,否则返回此静态对象.
- 回头看示例,并没有提及new出来的对象析构的问题,这是因为这个静态对象要在整个程序的生命周期,都要求存在,所以,此时单例模式没有考虑析构.
- 完成代码
#include <iostream> #include <string> using namespace std; class SObject { static SObject* c_instance; SObject(){} SObject(const SObject&); SObject operator=(const SObject&); public: void print() { cout << "this = " << this << endl; } static SObject* GetInstance(); }; SObject* SObject::c_instance = NULL; SObject* SObject::GetInstance() { if(c_instance == NULL) c_instance = new SObject; return c_instance; } int main() { SObject* s = SObject::GetInstance(); SObject* s1 = SObject::GetInstance(); SObject* s2 = SObject::GetInstance(); SObject* s3 = SObject::GetInstance(); s->print(); s1->print(); s2->print(); s3->print(); return 0; }