1. 为什么需要单例模式
2. 什么是单例模式
3. 如何创建单例模式
3.1 禁止类外部创建对象(私有化构造函数)
- 单例模式中对象的唯一性是由对象的实现者保证的。通过私有化构造函数 和 拷贝构造函数(因为缺省的构造函数都是公有的)来禁止在类的外部创建对象。
- 其中,拷贝构造函数声明就好,不需要写具体实现,它是有缺省实现的。声明它只是为了防止拷贝构造函数被调用,并不会真的去使用它。
3.2 类自己维护其唯一对象(私有静态成员变量)
- 因为如果不加 static, 编译器编译时是要确定类的大小的,类的大小又直接取决于所有类成员的大小,但这里的类成员 instance 的大小又取决于 定义它的类 Singleton, 这样就相应依赖了。语法上是不被允许的。
- 而加了 static, s_instance 就可以理解是一个被限定在类Singleton中使用的Singleton类 类型的 全局变量。而类Singleton 创建对象s_instance时,不会用到 s_instance 这个全局变量。类Singleton的大小就被确定下来了。
- 但是… 如果 写成 Singleton* s_instance; 又不会报错, 那这又是为什么?
3.3 提供访问单例对象的方法(静态成员函数)
- 获取单例对象的函数,必须是一个静态成员函数。
- 虽然普通成员函数也能访问到静态成员变量,但 普通成员函数 的调用前提是得先实例化一个对象,加上类内部的静态成员对象,这就至少有两个对象了,就不能叫单例了。
- 并且单例构造函数是私有的,也实例化不了对象。
4. 饿汉式和懒汉式
4.1 饿汉式
- 比如计时器,需要频繁使用,但是所占用内存由少,就很适合懒汉式。
#include <iostream>
#include <cstring>
using namespace std;
class Singelton{
public:
static Singelton& getInstance(void){
return s_instance;
}
private:
Singelton(int data = 0):m_data(data){
cout << "单例对象被创建" << endl;
}
Singelton(const Singelton&){}
static Singelton s_instance;
int m_data;
};
Singelton Singelton::s_instance = 1234;
int main(void){
cout << "main函数开始执行" << endl;
Singelton& s1 = Singelton::getInstance();
Singelton& s2 = Singelton::getInstance();
cout << &s1 << endl;
cout << &s2 << endl;
return 0;
}
$ ./a.out
单例对象被创建
main函数开始执行
0x601194
0x601194
4.2 懒汉式
- 比如任务管理器,用的不频繁,占用内存又多,适合用懒汉式。
#include <iostream>
#include <cstring>
using namespace std;
class Singelton{
public:
static Singelton& getInstance(void){
if(s_instance == NULL){
s_instance = new Singelton(1234);
}
s_count++;
return *s_instance;
}
void release(void){
if(s_count-- == 0){
delete s_instance;
s_instance = NULL;
}
}
void print(void){
cout << m_data << endl;
}
private:
Singelton(int data = 0):m_data(data){
cout << "单例对象被创建" << endl;
}
Singelton(const Singelton&){}
~Singelton(void){
cout << "单例对象被销毁" << endl;
}
static Singelton *s_instance;
static int s_count;
int m_data;
};
Singelton* Singelton::s_instance = NULL;
int Singelton::s_count = 0;
int main(void){
cout << "main函数开始执行" << endl;
Singelton& s1 = Singelton::getInstance();
Singelton& s2 = Singelton::getInstance();
Singelton& s3 = Singelton::getInstance();
cout << &s1 << endl;
cout << &s2 << endl;
cout << &s3 << endl;
s1.print();
s1.release();
s2.print();
s2.release();
s3.release();
return 0;
}
$ ./a.out
main函数开始执行
单例对象被创建
0xef6030
0xef6030
0xef6030
1234
1234