软件开发常用设计模式—单例模式总结(c++版)
单例模式:就是只有一个实例。
singleton pattern单例模式:确保某一个类在程序运行中只能生成一个实例,并提供一个访问它的全局访问点。这个类称为单例类。如一个工程中,数据库访问对象只有一个,电脑的鼠标只能连接一个,操作系统只能有一个窗口管理器等,这时可以考虑使用单例模式。
众所周知,c++中,类对象被创建时,编译系统为对象分配内存空间,并自动调用构造函数,由构造函数完成成员的初始化工作,也就是说使用构造函数来初始化对象。
1、那么我们需要把构造函数设置为私有的 private,这样可以禁止别人使用构造函数创建其他的实例。
2、又单例类要一直向系统提供这个实例,那么,需要声明它为静态的实例成员,在需要的时候,才创建该实例。
3、且应该把这个静态成员设置为 null,在一个public 的方法里去判断,只有在静态实例成员为 null,也就是没有被初始化的时候,才去初始化它,且只被初始化一次。
通常我们可以让一个全局变量使得一个对象被访问,但它不能阻止你实例化多个对象。如果采用全局或者静态变量的方式,会影响封装性,难以保证别的代码不会对全局变量造成影响。
一个最好的办法是,让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法,单例模式比全局对象好还包括,单例类可以继承。
单例模式又分为两种基本的情形:饿汉式和懒汉式
直接在静态区初始化 instance,然后通过 get 方法返回,这样这个类每次直接先生成一个对象,好像好久没吃饭的饿汉子,急着吃饭一样,急切的 new 对象,这叫做饿汉式单例类。或者是在get 方法中才 new instance,然后返回这个对象,和懒汉子一样,不主动做事,需要调用 get 方法的时候,才 new 对象,这就叫做懒汉式单例类。
小结:
懒汉式单例模式是用时间换取控件,饿汉式单例模式,是用空间换取时间。
继续查看单例模式:单例模式在实际开发过程中是很有用的,单例模式的特征总结:
1、一个类只有一个实例
2、提供一个全局访问点
3、禁止拷贝
逐个分析:
1、实现只有一个实例,需要做的事情:将构造函数声明为私有
2、提供一个全局访问点,需要做的事情:类中创建静态成员和静态成员方法
3、禁止拷贝:把拷贝构造函数声明为私有,并且不提供实现,将赋值运算符声明为私有,防止对象的赋值。
单例类de测试,两个方法:
1、实例化多个对象,看调用了几次构造函数,如果只调用一次,说明只创建一个实例
2、单步跟踪,查看对象的地址,是否一样,一样则为一个对象
完整的单例模式类代码:
class Singleton { public: //get 方法static Singleton * getInstance(){ if (NULL == instance) { lock(); //判断单例否if (NULL == instance) { instance = new Singleton(); } unlock(); } //返回一个实例化的对象return instance; } //c++ 嵌套的内部类,作用是删除单例类对象,Garbage被定义为Singleton的私有内嵌类,以防该类被在其他地方滥用。class Garbage { public: ~Garbage(){ if (Singleton::instance != NULL) { cout << "单例类的唯一实例被析构了" << endl; delete Singleton::instance; } } }; private: //单例类中定义一个这样的静态成员变量,而它的唯一工作就是在析构函数中删除单例类的实例,利用程序在结束时析构全局变量的特性,选择最终的释放时机;static Garbage garbage; //声明一个静态的实例static Singleton *instance; //单例类的私有构造函数 Singleton(){ cout << "调用了单例类的构造函数" << endl; } //单例类的私有析构函数 ~Singleton(){ cout << "调用了单例类的析构函数" << endl; } //把拷贝构造函数声明为私有,就可以禁止外人拷贝对象,也不用实现它,声明私有即可 Singleton(const Singleton ©); //把赋值运算符重载为私有的,防止对象之间的赋值操作 Singleton & operator=(const Singleton &other); }; //初始化内部似有泪的静态变量,目睹是启动删除的析构函数,如果不初始化,就不会被析构 //内部类可以访问外部类的私有成员,外部类不能访问内部类的私有成员!Singleton::Garbage Singleton::garbage; //初始化instance为 null Singleton * Singleton::instance = NULL; int main(void) { Singleton *a = Singleton::getInstance(); Singleton *b = Singleton::getInstance(); Singleton *c = Singleton::getInstance(); if (a == b) { cout << "a = b" << endl; } return 0; }