1,本节课讲述单例类模式,实现并抽取相关代码实现单例类模板,在以后开发工作 中,如果想要使用单例模式,那么直接使用今天开发的单例类模板就可以;
2,需求的提出:
1,在架构设计时,某些类在整个系统生命期中最多只能有一个对象存在 ( Single Instance );
1,如超市收银系统,由外观来说其由显示器、扫描枪、收款箱组成,这几部分都只有一个部件,用面向对象的思想来进行架构设计的话,扫描枪应该对应到代码里面的一个类,它应该用来创建对象,实际的硬件只有一个扫描枪,肯定要限制扫描枪对应的类只能创建一个对象;
2,这个时候单例模式的需求就出来了;
3,问题:
1,如何定义一个类,使得这个类最多只能创建一个对象?
4,单例模式:
1,要控制类的对象数目,必须对外隐藏构造函数;
1,要创建一个对象,必然要调用构造函数,因此可以控制构造函数的访问属性;
2,思路:
1,将构造函数的访问属性设置为 private;
1,外界就不能创建对象了;
2,定义 instance 并初始化为 NULL;
3,当需要使用对象时,访问 instance 的值;
1,空值:创建对象,并用 instance 标记;
2,非空值:返回 instance 标记的对象;
5,单例模式初探编程实验:
#include <iostream> #include <string> using namespace std; class SObject { static SObject* c_instance; // 定义标识符指针; /* 不需用拷贝和赋值 */ SObject(const SObject&); SObject& operator= (const SObject&); SObject() // 构造函数创建为私有的; { } public: static SObject* GetInstance(); void print() { cout << "this = " << this << endl; } }; 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(); s->print(); // this = 0x940a008 s1->print(); // this = 0x940a008 s2->print(); // this = 0x940a008 return 0; }
1,上述代码中并没有释放这个唯一的对象,这是因为单例模式所对应的对象在系统的生命周期中都是存在的,如果这个系统还在运行,就不需用释放它;
2,单例模式所得到的对象在整个系统运行过程中是绝对不释放的;
6,单例模式存在问题(这里做的是锦上添花的事,要求完美):
1,需要使用单例模式时:
1,必须定义静态成员变量 c_instance;
2,必须定义静态成员函数 GetInstance();
2,如果现在要开发超市收银系统,那么开发扫描枪对应的类需要用单例模式来实现,收款箱对应的类也要用单例模式来实现,这个时候就要写重复的静态成员变量和静态成员函数;
3,静态成员变量和静态成员函数和我们类的实际功能没有关系,这是单例模式的逻辑;
7,解决方案:
1,将单例模式相关的代码抽取出来,开发单例类模板,当需要单例类时,直接使用单例类模板;
8,单例类模板编程实验:
1,单例模式类模板 Singleton.h 文件:
1 #ifndef _SINGLETON_H_ 2 #define _SINGLETON_H_ 3 4 template 5 < typename T > 6 class Singleton 7 { 8 static T* c_instance; 9 public: 10 static T* GetInstance(); 11 }; 12 13 template 14 < typename T > 15 T* Singleton<T>::c_instance = NULL; 16 17 template 18 < typename T > 19 T* Singleton<T>::GetInstance() 20 { 21 if( c_instance == NULL ) 22 { 23 c_instance = new T(); 24 } 25 26 return c_instance; 27 } 28 29 #endif
2,单例模式的使用:
1 #include <iostream> 2 #include <string> 3 #include "Singleton.h" 4 5 using namespace std; 6 7 class SObject 8 { 9 friend class Singleton<SObject>; // 当前类需要使用单例模式 10 11 SObject(const SObject&); 12 SObject& operator= (const SObject&); 13 14 SObject() 15 { 16 } 17 public: 18 19 void print() 20 { 21 cout << "this = " << this << endl; 22 } 23 }; 24 25 int main() 26 { 27 SObject* s = Singleton<SObject>::GetInstance(); 28 SObject* s1 = Singleton<SObject>::GetInstance(); 29 SObject* s2 = Singleton<SObject>::GetInstance(); 30 31 s->print(); // 0x9621008; 32 s1->print(); // 0x9621008; 33 s2->print(); // 0x9621008; 34 35 return 0; 36 }
3,使用单例类模板方法:
1,构建对象的函数全部私有化;
2,声明单例类模板为此类的友元(可以访问这个类);
4,此单例类模板在我们今后开发工作中都可以使用;
9,小结:
1,单例模式是开发中最常用的设计模式之一;
2,单例模式的应用使得一个类最多只有一个对象;
3,可以将单例模式相关的代码抽象成类模板;
4,需要使用单例模式的类直接使用单例类模板;