c++单例模式singleton实现
2017-04-30
1.singleton 单例模式:
设计一个类,我们只能生成该类的一个实例。eg. 地球就是一个singleton,据我们所知,宇宙中目前只有一个地球。
2.实现思路:
设一个static private变量:instance。每次要生成该类实例时都检查一下这个instance是否为nullptr:是的话就新建一个实例赋给该instance,否的话就直接返回这个实例。
为什么instance需要是static的呢?
因为instance应该是一个类变量,它需要被整个class共享,static关键字在上一篇笔记中讲过:它可以限制变量的作用域,static变量在类中就会变成类变量,整个类的实例都能访问。如果是实例变量的话,那么每个实例都将拥有分别拥有各自的instance,就无从判断该类是不是已经有一个实例了。
eg. 宇宙在创造地球的时候,为了让人类珍惜赖以生存的家园,它决定整个宇宙中只能有一个地球,但是它要创造的星球很多,常常忘记已经创造了哪个,还没创造哪个。所以为了保证只有一个地球,它把地球类设计成了单例模式,并且给了这个类一张白纸。有一天它决定要创造地球了,于是就先让地球出示了那张纸,它发现:那张纸是空白的,这说明地球还没有被创造过,所以它就选好了一个位置(内存),并把这个位置记在了白纸上,然后它在这个位置上创造了地球。一个月后,忙碌的宇宙又想起了创造地球这件事,但是它不确定自己是否已经创造过地球了,于是它找到地球类,让它出示那张纸,发现那张纸上已经有一个地址了!地球类对宇宙说:“我已经有一个实例了,它就在这个纸上写的位置上,不信你去瞧瞧!”宇宙按照地址找到了地球,发现它就在那里,于是宇宙就决定进行下一步:改善地球环境。这当然都是后话了。
为什么instance需要是private的呢?
因为如果instance是public的,那么任意一个该类的实例都可以修改它的值,比如:创建完一个实例之后,编程人员不小心把instance又置为了nullptr,那么下次就还能够创建新的实例,这是不符合单例模式宗旨的。
3.实现代码:
|
|
运行结果图:
我说说我有疑问的的几点:
- instance变量为什么是Singleton*类型,不能是Singleton或者Singleton&类型?
答:如果是Singleton类型:那就是递归结构了,自身包含自身,没法做到只有一个实例;
如果是Singleton&引用类型,对于引用类型的成员, 只能通过初始化表达式进行初始化。Singleton(Singleton &s):instance(s) { },这还是递归结构嘛,先有鸡还是先有蛋的问题。 - instance变量如何初始化呢?
答:在类的外面,初始化为nullptr。不能在里面初始化,否则zongshinullptr,总能创建新的实例。 - 构造函数和析构函数为什么是private的?
答:构造函数是private:构造函数就是生成实例的,如果public则其他实例可以被任意生成;
析构函数在实例被销毁时自动调用,析构函数只能有一个, 不能被重载。析构函数可以被显式的调用, 以释放对象中动态申请的内存。如果析构函数是public,则实例将能够被随意销毁,instance变量如果没有了,下次就不能够再生成了。 - 为什么~Singleton()析构函数没有被调用,而构造函数被调用了?
答:因为new Singleton()所以构造函数被调用了,以instance地址为起点,开辟了一块空间,给instance变量进行了初始化;
因为该实例存在于静态存储区,static的变量要程序关闭才会释放。 - 如何验证这个类真的只有一个实例?
答:在本例中,==用来判断两个指针是否相同,即判断两个实例是否在同一个地址。