概念
在内存中只会创建,且仅创建一次对象的设计模式;作用:在程序中多次使用同一个对象且作用相同时,可用单例模式避免频繁创建对象导致内存飙升。有懒汉与饿汉两种模式。
分类
懒汉式:在真正需要使用对象时采取创建该单例类对象。方式:程序使用对象前,先判空,若为空则直接进行实例化操作;若不为空,则直接返回对象。缺点:存在线程安全问题,即多线程同时第一次调用该对象时,此时判断都为空,则会导致创建多个实例化对象,造成内存泄露。解决方式:加锁,但是访问该单例对象过于频繁的话,那么加锁的操作会导致程序性能降低;所以在加锁的时候,应尽可能减小锁粒度的大小,增大并发性能。
其中,关键在于:
//在类定义中,将instance声明为静态成员变量
//在.cpp源文件中进行静态成员变量instance的定义和初始化为空指针
SingleDll* SingleDll::instance = nullptr;
SingleDll *SingleDll::getInstance()
{
if(!instance)
instance = new SingleDll();
return instance;
}
饿汉式:在类加载的时候就已经创建好了该单例对象。
其中,关键在于:
//在类定义中,将instance声明为静态成员变量
//在.cpp源文件中进行静态成员变量instance的定义和初始化
SingleDll* SingleDll::instance = new SingleDll();
//由于instance的初始化是在编译时就完成了,所以是线程安全的
选取方式:在开发中,若是对内存要求非常高,则使用懒汉式单例模式,可在特定时候才创建对象;若是对内存要求不高,则使用饿汉式单例模式,因为简单不易出错,且无并发性能与安全的问题。
加载单例模式DLL
linux下单例模式+动态库+回调函数Demo
补充
C++内存分区:
栈、堆、全局/静态存储区、常量存储区、代码区。
栈:存放函数的局部变量、函数参数、返回地址等,由编译器自动分配和释放。
堆:动态申请的内存空间,有程序员进行分配和释放,若程序执行结束未释放,则会由操作系统自动回收。(即程序中存在的内存泄露,会在程序执行结束后,由操作系统进行回收)。
全局/静态存储区:存放全局变量和静态变量。程序运行结束后由操作系统自动释放。
常量存储区:存放常量,不允许修改,程序运行结束自动释放。
代码区:存放代码,不允许修改,但可以执行。(编译后的二进制文件就存放在这里)。