最近在学习设计模式方面的知识,随笔整理。
单例模式:自己来判断是否已经实例化。保证一个类仅有一个实例,并提供一个访问它的全局访问点。
本质:①定义私有的本类静态对象、对象指针或对象引用;
②将该类的构造函数设为private,防止外部用new来实例化它;
③外部仅能通过公有静态成员函数获得唯一对象。
UML:
实现方式:懒汉式 饿汉式
懒汉式:当程序第一次访问单件模式实例时才进行创建。代码如下:
static Singleton *instance_s;
Singleton* Singleton::instance_s=0;Singleton* Singleton::Ins()//懒汉单例模式:即对象在函数首次被访问时创建。{if(instance_s==0){instance_s = new Singleton;}return instance_s;}
饿汉式:在程序启动或单件模式类被加载的时候,单件模式实例就已经被创建。代码如下:
static Singleton* instance_s ;//类内私有
Singleton* Singleton::instance_s=new Singleton;//类外初始化
Singleton *Singleton::Ins()//类内公有静态函数外部实现
{
return instance_s;
}析构方法:
#include <QObject>
#include<QDebug>
class Singleton : public QObject
{
Q_OBJECT
private:
explicit Singleton(QObject *parent = 0);
static Singleton* instance_s ;
class Garbo
{
public:
~Garbo()
{
if(Singleton::instance_s)
{
qDebug()<<"destructor called";
delete Singleton::instance_s;
Singleton::instance_s = NULL;
qDebug()<<instance_s;
}
}
};
static Garbo garbo;
public:
~Singleton();
static Singleton* Ins();
};
Singleton::Garbo Singleton::garbo;
如果程序 运行期间都不会析构,那你程序退出也就没必要析构了,操作系统自动回收内存。另外,如果你的静态成员是 static classB b;
程序结束时,自动调用析构。
参考:Qt浅谈之一:内存泄露(总结)
Qt中内存泄露和退出崩溃的问题
如何选择:如果单例模式实例在系统中经常会被用到,饿汉式是一个不错的选择。
反之如果单例模式在系统中会很少用到或者几乎不会用到,那么懒汉式是一个不错的选择。
种类:单线程模式 多线程模式
单线程模式比较简单,见实现方式。
多线程一般采用双重锁定机制来保证安全性,可参考:Qt中实现单例模式(SingleTon)
多线程安全的单例模式可参考:http://wiki.qt.io/Qt_thread-safe_singleton
应用场合:高并发模式下,维持数据库连接的唯一性;GUI编程中弹窗的唯一性;需要频繁实例化然后销毁的对象;创建对象时耗时过多或者耗资源过多,但又经常用到的对象;频繁访问数据库或文件的对象。以及其他所有要求只有一个对象的场景,例如资源管理器、打印机、通信端口等。
可参考:设计模式之——单例模式(Singleton)的常见应用场景
补充:在《设计模式:可复用面向对象软件的基础》一书中对单例模式的适用性有如下描述:
1、当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。
2、当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。
相关博文:设计模式之单例模式(C++)