设计模式:单例模式

本文探讨了单例模式的定义,强调在实现中如何确保类只有一个实例并提供全局访问点。在多线程环境中,通过双重NULL检查和锁来处理并发创建实例的问题,以保证单例模式的正确性。同时,文章提到了优化方法,以减少不必要的锁操作,提高效率。此外,还指出单例模式通常避免外部指针,以防止额外的处理问题。
摘要由CSDN通过智能技术生成

 提示:本文是作者根据——程洁《大话设计模式》的总结和感悟,内容可能不涉及相关代码实现,或许不适合初学,仅作参考,请有条件的读者购书进行系统学习,或浏览其他网页进行学习。

单例模式 

  1. 目录

    单例模式 

    1.单例模式定义

    2.单例模式实现遇到的问题


 1.单例模式定义

       定义: 保证一个类仅有一个实例,并提供一个访问它的全局访问点

       从实现上讲,为了使类,只有一个实例,那相关的 构造函数、拷贝构造函数、析构函数都应该是private属性。除此之外仅仅提供:里的公有方法GetInstance(),以及DestroyInstance();通过这两个函数对类对象进行创建和销毁。代码如下

#include <iostream>
#include <Windows.h>
using namespace std;

HANDLE mutex; //创建全局锁

class Singlton
{
private:
	Singlton(){};//此处需要加括号,代表此函数已经实现,否则报连接期错误
	~Singlton(){};
	Singlton(const Singlton& S);
	Singlton& operator=(const Singlton& S){};
	static Singlton *pInstance;//指向实例化对象的类内指针

public:
/*API_1:获得类的 实例化对象*/	
    static Singlton* GetInstance()
	{
		mutex = CreateMutex(NULL, FALSE, NULL);//全局锁在此处初始化
		if(pInstance == NULL)
		{
			WaitForSingleObject(mutex, INFINITE);
			if(pInstance == NULL)
			{	
				pInstance = new Singlton;
			}
                         ReleaseMutex(mutex);
		}
        return pInstance;
	}
/*API_2:销毁类的实例化对象*/
    static void DestoryInstance() 
	{
		if(pInstance)
		{
			delete pInstance;
			pInstance = NULL;
			CloseHandle(mutex);
		}
	}
/*API_3:测试函数*/
	void Fun()
	{
		printf("HHH");
	}
};
 Singlton* Singlton::pInstance = Singlton::GetInstance();
 
int main()
{ 
	GetInstance().Fun();
	GetInstance().DestoryInstance();
	//单例模式一般直接用函数调用
	return 0;
}

在上述代码中,API_2中为什么采用两层 NULL 判断 并且还加锁:主要是为了适应多线程环境,如果很多线程都要取使用这个类对象,说好的单例模式呀,只能有一个对象,此处代码成因如下:                                                                                                                                      所以第一次判断是否为空,空的话,就创建新对象,不是的话就就返回已经创建好的实例,相当于多个指针指向同一个对象

if(pInstance == NULL)
{
    pInstance = new Singlton;
}
    reutrn pInstance;

那么问题来了,如果是多线程环境,执行同一段代码,赶巧了,都判断时空,咋整?所以要考虑加锁

mutex = CreateMutex(NULL, FALSE, NULL);//全局锁在此处初始化
	 
WaitForSingleObject(mutex, INFINITE);
if(pInstance == NULL)
{	
    pInstance = new Singlton;
    ReleaseMutex(mutex);
    return pInstance;
}
ReleaseMutex(mutex);

return pInstance;

多线程问题解决了,但是好像效率不太高,你想下,如果此时实例的对象不为空:进入锁,判断是否为空,空,创建,解锁,返回。但如果不为空呢,进入锁,判断是否为空,非空,解锁,返回。哪怕是不为空都要进入一次锁,太耗费时间了,所以才有的在此代码基础上,外层套一个判断是否为空,以此提高效率。

static Singlton* GetInstance()
{
	mutex = CreateMutex(NULL, FALSE, NULL);//全局锁在此处初始化
	if(pInstance == NULL)
	{
		WaitForSingleObject(mutex, INFINITE);
		if(pInstance == NULL)
		{	
			pInstance = new Singlton;
			ReleaseMutex(mutex);
		}
		return pInstance;
	}
}

2.单例模式实现遇到的问题

单例模式一般是函数直接调用,不用外部指针去接。如果去接的话可能会带来很多不必要的处理问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值