C++深入浅出单例模式---不仅仅是单例
前言:看到我的标题你也许会很奇怪,明明是讨论单例模式,为什么又说不仅仅是单例模式呢?图样图森破!我在这里想和大家分享的不仅仅是JAVA设计模式中的单例模式(Singleton),还有C++中的单例模式,以及单例模式的原理。总之一句话,不服来辩!
对于很多从事JAVA编程或者C++编程超过1年的工友来说,就单例模式而言可谓是熟悉的不能再熟悉了吧?So easy!简单的说,就是保持对一个实例的全局范围内的唯一访问途径。上面的话有点绕口,换言之就是无论我们在其他任何类的代码中想要访问某个类的实例,都可以通过单例模式或者在全局范围内唯一的该实例,就像下面的代码:[java] view plaincopyclass Singleton{ private static Singleton instance; private Singleton(){ //todo } public static Singleton getInstance(){ if(instance == null) { instance = new Singleton(); } return instance; } } 上面这段是Java的单例模式的简单实现,有几点值得我们注意:(1)类Singleton的构造方法是private的,其成员对象也是private的,这就保证了只能通过单例模式提供的方法来访问该类的实例。(2)成员对象instance是static的,这是单例模式的原理和重点。为什么?容本细细道来,在java中,static关键字的含义就是不属于任何类的实例,而是属于类本身,更重要的是,static修饰的对象和变量会在类第一次被加载时存储在内存中的静态储存区域,只要程序在运行,这块区域就不会被清除掉,也就是说static修饰的instance会一直保存在静态储存区域并且只有一份。所以我们在其他类访问instance的时候,都是访问的这块区域,这就是单例模式的原理所在。(3)在其他类的代码中要访问Singleton实例都可以通过如下的方法:[java] view plaincopySingleton singleton = Singleton.getInstance(); (4)扯点题外话,getInstance方法在多线程的情况下,最好加上同步的关键字,以免发生意外情况。好了,上面我们讨论了下java中的单例模式,那么在C++中的单例模式又是怎么样的呢?其实大同小异,只是C++中有了全局变量一说,所以略有不同,我们以Android系统中的ProcessState.cpp为例讲解下:在frameworks/frameworks/base/include/private/binder的Static.h中,声明了一个全局变量[cpp] view plaincopy// For ProcessState.cpp extern sp<ProcessState> gProcess; 而在frameworks/frameworks/base/libs/binder的ProcessState.cpp中,针对这个全局变量提供了单例模式:[cpp] view plaincopy#include <private/binder/Static.h> ................................... sp<ProcessState> ProcessState::self() { if (gProcess != NULL) return gProcess; AutoMutex _l(gProcessMutex); if (gProcess == NULL) gProcess = new ProcessState; return gProcess; } ProcessState对于每个进程来说都是独一无二的,所以Android系统为ProcessState设计了单例模式来访问它,就像下面这样的代码[cpp] view plaincopyProcessState::self() 而ProcessState的构造函数是ProcessState.h中是private的,所以我们无法在其它类中直接调用构造函数来实例化[cpp] view plaincopyprivate: friend class IPCThreadState; ProcessState(); ~ProcessState();