概念:单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例。
实现方式:实现单例模式通常有两种方式,一种是饿汉方式,另一种是懒汉方式。饿汉方式是指在main函数开始之前创建实例,优点是能避免多进程多线程异步IO,缺点是实例伴随整个程序的生命周期,消耗资源。懒汉方式是指在程序第一次调用getInstance函数时创建实例,优点是减小系统的资源消耗,缺点是当未提供同步IO方案时,可能出现多个实例的现象。
写饿汉模式的步骤:
1、在类的内部,定义私有的构造函数、拷贝构造函数、析构函数。
2、在类的内部,定义私有的指向实例化对象的静态指针;在类的外部,初始化该静态指针(在堆上创建该类唯一的实例化对象)。
3、在类的内部,定义公有的返回对象地址的静态成员函数getInstance()。
用C++语言实现一个简单的单例模型(饿汉), 代码如下:
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 class President 6 { 7 public: 8 static President *getInstance() //对应步骤三 9 { 10 return mPresident; 11 } 12 void Speak(const string &str) 13 { 14 cout << "Mr.president said : " << str << "." << endl; 15 } 16 private: 17 President(){} //对应步骤一 18 President(const President &president) {} //对应步骤一 19 ~President(){} //对应步骤一 20 private: 21 string mName; 22 int age; 23 static President *mPresident; //对应步骤二 24 }; 25 26 President *President::mPresident = new President; //对应步骤二 27 28 void test() 29 { 30 President *p1 = President::getInstance(); 31 President *p2 = President::getInstance(); 32 p1->Speak("同志们好!"); 33 p2->Speak("空谈误国,实干兴邦"); 34 if (p1 == p2) 35 cout << "同一个实例" << endl; 36 else 37 cout << "不同的实例" << endl; 38 } 39 40 int main(void) 41 { 42 test(); 43 return 0; 44 }
test()运行结果:
私有构造函数:使得在类外无法实例化对象。
私有拷贝构造函数:使得无法通过已有的对象来实例化对象。
私有析构函数:使得堆上的实例化对象在程序运行过程中无法被释放。
在类的内部,定义私有的指向实例化对象的静态指针:用于保存在堆上创建的对象的地址
在类的外部,初始化该静态指针:静态成员初始化在main函数之前,又因为静态指针是成员变量,因此可以调用私有的构造函数。
静态成员函数getInstance():操作静态指针,返回唯一的实例化对象。
1 #include <iostream> 2 using namespace std; 3 4 class Demo 5 { 6 public: 7 static Demo *getInstance() //第一次调用时创建实例 8 { 9 if (NULL == pInstance) 10 { 11 pInstance = new Demo; 12 } 13 return pInstance; 14 } 15 private: 16 Demo(){} 17 Demo(const Demo &demo) {} 18 ~Demo(){} 19 private: 20 static Demo *pInstance; 21 }; 22 23 Demo *Demo::pInstance = NULL; 24 25 int main(void) 26 { 27 Demo *p = Demo::getInstance(); 28 Demo *p1 = Demo::getInstance(); 29 return 0; 30 }
通过如上操作,这个类就只能创建一个实例化对象。这就是单例模型。