单例模式
概述
保证一个类、只有一个实例存在,同时提供能对该实例加以访问的全局访问方法。
三个要点:
一是某个类只能有一个实例;
二是它必须自行创建这个实例;
三是它必须自行向整个系统提供这个实例。
模式中的角色和职责
Singleton(单例):在单例类的内部实现只生成一个实例,同时它提供一个静态的getInstance()工厂方法,让客户可以访问它的唯一实例;为了防止在外部对其实例化,将其构造函数设计为私有;在单例类内部定义了一个Singleton类型的静态对象,作为外部共享的唯一实例。
单例模式的使用步骤:
a) 构造函数私有化。
b) 提供一个全局的静态方法(全局访问点)来获取单例对象。
c) 在类中定义一个静态指针,指向本类的变量的静态变量指针 。
单例模式的案例
1 #include <iostream> 2 using namespace std; 3 /* 4 懒汉模式 5 */ 6 class Singelton 7 { 8 public: 9 /* 10 对外提供一个全局的静态⽅方法 11 */ 12 static Singelton * getInstance() { 13 /* 14 懒汉式: 在调⽤用全局静态⽅方法,获取单例的时候, 15 再进⾏行创建。懒汉式的单例创建在程序的执⾏行中进⾏行。 16 */ 17 if (instance == NULL) { 18 instance = new Singelton; 19 } 20 m_count++; 21 return instance; 22 } 23 int getCount() { 24 return m_count; 25 } 26 private: 27 /* 28 构造函数私有化 29 */ 30 Singelton() { 31 instance = NULL; 32 m_count = 0; 33 cout << "构造函数 singelton() 执⾏行" << endl; 34 } 35 /* 36 在类中定义一个静态指针,指向本类的变量的静态变量指针 37 */ 38 static Singelton *instance; 39 static int m_count; 40 }; 41 /* 42 对静态变量的初始化,要放在类的外部, 43 即,放在全局位置上。 44 */ 45 Singelton * Singelton::instance = NULL; 46 int Singelton::m_count = 0; 47 /* 48 饿汉模式 49 */ 50 class Singelton2 { 51 public: 52 static Singelton2* getInstance() { 53 m_count++; 54 return instance; 55 } 56 int getCount() { 57 return m_count; 58 } 59 private: 60 Singelton2() { 61 instance = NULL; 62 m_count = 0; 63 } 64 static Singelton2 * instance; 65 static int m_count; 66 }; 67 /* 68 饿汉式的不是在全局静态⽅方法中创建, 69 ⽽而是不管你创不创建实例,我在声明的 70 时候就创建出来, 71 饿汉式的单例,是在编译的时候就已经创建好了。 72 */ 73 Singelton2 * Singelton2::instance = new Singelton2; 74 int Singelton2::m_count = 0; 75 int main(void) 76 { 77 Singelton * singer = Singelton::getInstance(); 78 cout << singer-‐>getCount() << endl; 79 Singelton * singer2 = Singelton::getInstance(); 80 cout << singer2-‐>getCount() << endl; 81 if (singer == singer2) { 82 cout << "二者是同⼀一个实例" << endl; 83 } 84 else { 85 cout << "二者不是同⼀一个实例" << endl; 86 } 87 cout << "-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐ 以下 是 饿汉式 -‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐" << endl; 88 Singelton2 * singer3 = Singelton2::getInstance(); 89 cout << singer3-‐>getCount() << endl; 90 Singelton2 * singer4 = Singelton2::getInstance(); 91 cout << singer4-‐>getCount() << endl; 92 if (singer3 == singer4) { 93 cout << "二者是同⼀一个实例" << endl; 94 } 95 else { 96 cout << "二者不是同⼀一个实例" << endl; 97 } 98 return 0; 99 }
单例模式的优缺点
优点:
(1) 单例模式提供了对唯一实例的受控访问。
(2) 节约系统资源。由于在系统内存中只存在一个对象。
缺点:
(1) 扩展略难。单例模式中没有抽象层。
(2) 单例类的职责过重。
适用场景
(1) 系统只需要一个实例对象,如系统要求提供一个唯一的序列号生成器或资源管理器,或者需要考虑资源消耗太大而只允许创建一个对象。
(2) 客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例。