单例模式可以说是所有23种设计模式中最为简单的一个,没有之一。其主要思想就是保证整个应用环境中,最多只会有一个对象的实例。类关系图参考如下:
在c++中,单例模式的实现,较为常用的实现方式一般为:
1 namespace singleton 2 { 3 /************************************************************************** 4 * create : (jacc.kim) [5-17-2016] 5 * summary : 单例类 6 **************************************************************************/ 7 Singleton* Singleton::ms_Instance = nullptr; 8 class Singleton 9 { 10 public: 11 ~Singleton() {} 12 static Singleton* getInstance() { 13 if (nullptr == ms_Instance) { 14 ms_Instance = new (std::nothrow) Singleton(); 15 } 16 return ms_Instance; 17 } 18 19 static void freeInstance() { 20 if (nullptr != ms_Instance) { 21 delete ms_Instance; 22 ms_Instance = nullptr; 23 } 24 } 25 26 private: 27 Singleton() {} 28 Singleton(const Singleton&) = delete; 29 Singleton& operator=(const Singleton&) = delete; 30 31 static Singleton* ms_Instance; 32 33 };//class Singleton 34 35 }//namespace singleton
其实还可以利用模板实现更加通用的单例设计。此种方式又可分为"is-a"形式与"has-a"形式。参考代码如下(以下是先前基于cocos2d-x v3.7版本搭的一个游戏框架中使用的代码):
1 #pragma once 2 3 #include "Framework/Foundation/GFGlobalDefine.h" 4 5 NSGF_BEGIN 6 7 /****************************************************************************** 8 * create : (jacc.kim) [8-18-2015] 9 * summary : class GFHaSingleton 10 ******************************************************************************/ 11 template<typename T> 12 class GFHaSingleton 13 { 14 public: 15 typedef T TSingletonClass; 16 17 public: 18 static TSingletonClass* getInstance(); 19 static void freeInstance(); 20 21 ~GFHaSingleton() {} 22 23 private: 24 static TSingletonClass* sm_Instance; 25 26 private: 27 GFHaSingleton(); 28 GFHaSingleton(const GFHaSingleton<T>&) DELETE_METHOD; 29 GFHaSingleton& operator=(const GFHaSingleton<T>&) DELETE_METHOD; 30 31 };//class GFHaSingleton 32 33 /****************************************************************************** 34 * create : (jacc.kim) [8-18-2015] 35 * summary : class GFIaSingleton 36 ******************************************************************************/ 37 template<typename T> 38 class GFIaSingleton : public T 39 { 40 public: 41 typedef T TSingletonClass; 42 43 public: 44 static GFIaSingleton* getInstance(); 45 static void freeInstance(); 46 47 virtual ~GFIaSingleton() {} 48 49 private: 50 static TSingletonClass* sm_Instance; 51 52 private: 53 GFIaSingleton(); 54 GFIaSingleton(const GFIaSingleton<T>&) DELETE_METHOD; 55 GFIaSingleton& operator=(const GFIaSingleton<T>&) DELETE_METHOD; 56 57 };//class GFIaSingleton 58 59 NSGF_END 60 61 #include "Framework/Foundation/GFSingletonTemplate.inl"
这种形式的单例使用将是非常方便的。例如:GFHaSingleton<YourClassName>::getInstance()->xxxxxxxx(........);
单例模式在实现应用中是十分频繁的,几乎任何一个项目都必需会用到该模式。值得注意的一点是:我们可以在设计上尽量避免不会产生多于一个的实例,但实际技术上,只要你想,总是有办法创建出多于一个的实例的,这样,例就不再是单例了。就比如前面的第一份参考代码中的 class Singleton; 类,从声明上看,确实只能是有一份实现。但我们可以利用一些高级技术手段创建出N份实例对象来。因此,我们所说的单例,只是在一定的约束下的单例,只是在设计上保证单例。(其实这样在实际项目中就足够了)。