我需要在软件里面做日志记录,所有类都要把日志信息写到同一个文件中,这时候需要一个新类去操作此文件实现类和日志文件的解耦和,每个类在写日志的时候只需要调用这个新日志类的一个接口,把日志信息丢给这个日志类去处理就可以了,这个日志类的实例对于整个软件来说,有一个就够了,只需要在类内部写文件的时候做资源互斥访问就可以了,这个类就可以做成单例模式。
单例模式描述一个独立的类,它负责自创建唯一实例并提供给其他类使用。有一些类在软件的整个生命周期中只需要一个实例,其他类使用此类的这一个实例就能达到预期效果。这种场景下就可以用到单例模式。
一、特征
自创建:
1、构造函数需要声明为私有的,其它类无法在外部实例化此类的对象。
唯一实例:
1、实例化的唯一对象为static成员变量,这样可以保证其它类访问的是属于此类(不是此类实例化的对象)的成员,并且可以确保此唯一对象的生命周期;
2、屏蔽编译器默认 为 此类增加的拷贝构造函数和赋值运算函数,确保唯一的准则。可以delete关键字屏蔽,也可以将唯一实例直接定义成指针变量。
提供给其他类使用:
1、实例化的唯一对象为私有的成员变量,这样避免外部类直接访问。
2、定义静态成员函数,获取唯一实例并提供给其他类使用。
二、实现
饿汉模式:
在单例类第一次被使用的时候创建唯一实例,避免内存浪费。
在多线程软件环境中,多个线程同时首次访问这个类,可能导致创建不只一个实例,所以此方式为非线程安全的,需要在创建唯一实例时加锁。这个时候就需要考虑效率问题;
懒汉模式:
顾名思义,就是在软件开始运行的时候就创建唯一实例,虽然内存浪费,但是不会有效率影响;
三、释放
单例模式中的唯一实例一般都是指向此类的静态指针,在不需要此单例类的时候需要释放在堆中new出来的内存。
手动释放:
在确认不需要单例类的时候手动调用单例类提供的资源回收接口,最好在主线程中调用函数,如果在多线程中调用需要考虑加锁;
自动释放:
我们可以定义一个类B,在单例类中创建一个私有的类B的成员变量,单例类在析构的过程中会析构它的成员变量,此成员变量在析构的时候释放这个唯一实例。因为类B要做的只是访问这个唯一实例,所以类B可以作为单例类的嵌套类使用。