概念
单例模式也称单子模式、单件模式,通过单例模式可以保证系统中只有一个类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享,对于系统中的某些类来说,只有一个实例很重要,比如一个打印机可以有多个打印任务,但是只有一个正在工作的任务,一个系统只能有一个窗口管理器或文件系统
要点
1. 单例类只能有一个实例
2. 它必须自行创建这个实例
3. 它必须自行向整个系统提供提供这个实例
从具体实现角度来说,就是以下三点:
1. 单例模式的类只提供私有的构造函数
2. 类定义中含有一个该类的静态私有对象
3. 该类提供了一个静态的公有的函数用于创建或获取它本身的静态私有对象
注意事项
一 :实例控制
单例模式会阻止其他对象实例化自己的单例对象的副本,从而确保所有对象都访问唯一实例
二 :灵活性
因为类控制实例化过程,所以类可以灵活更改实例化过程
三: 开销
虽然数量很少,但如果每次对象请求引用时都要检查是否存在类的实例,将仍然需要一些开销,这个问题可以通过静态初始化解决此问题
定义一个私有的静态指针m_sInstance,和一个公有的静态函数 GetInstance(),
单例模式又分为饿汉式单例和懒汉式单例,饿汉式单例在单例类被加载时就实例化一个对象交给自己的引用;而懒汉式在调用取得实例方法的时候才会实例化对象
单例模式的优点:
1. 在内存中只有一个对象,节省内存空间
2. 避免频繁的创建销毁对象,可以提高性能
3. 避免对共享资源的多重占用
4. 可以全局访问
单例模式的适用场景:
1. 需要频繁实例化然后销毁的对象
2. 创建对象耗时过多或者耗资源过多,但又经常用到的对象
3. 有状态的工具类对象
4. 频繁访问数据库或文件的对象
5. 以及其他要求只有一个对象的场景
懒汉与饿汉
单例大约有两种实现方法:懒汉与饿汉。
懒汉:故名思义,不到万不得已就不会去实例化类,也就是说在第一次用到类实例的时候才会去实例化,所以上边的经典方法被归为懒汉实现;
饿汉:饿了肯定要饥不择食。所以在单例类定义的时候就进行实例化。
懒汉式单例实现如下:
注意:此方式是单线程模式下,是可行的,多线程下需要考虑线程安全,
class PInstance{
public:
PInstance();
virture ~PInstance();
static PInstance* GetInstance(){
static PInstance* instance;
if(instance == NULL){
instance = new PInstance();
return instance;
}
}
};
线程安全的懒汉式单例实现例子很多,可查找相关资料,反正我是不用
而我也是一个喜欢使用饿汉式的“懒汉“
线程安全的饿汉式单例实现如下:
class PInstance{
public:
static PInstance* GetInstance();
protected:
PInstance(){}
virture ~PInstance();
private:
static PInstance* p;
};
PInstance* PInstance::p = new PInstance();
PInstance* PInstance::GetInstance(){
return p;
}
这两种简单的方法分别解决了单线程和多线程的实例多创建的问题,保证了实例的唯一性