C++Singleton模式

Singleton模式: (单例模式)整个类只能生成一个对象

单例模式的三种经典设计方案:

1.延时加载,也称为懒汉模式,需要时才会创建对象;
2.贪婪加载,也称为饿汉模式,在程序执行前就已经创建好对象;
3.双重锁模式,延时加载升级版,加锁线程安全,需要时创建对象;

单例模式特点:

1.屏蔽生成对象的接口 ;
2.类中提供接口 来生成唯一对象 ;
(1.不能以类类型的方式返回
(2.接口是静态函数

一、延时加载

适用于单线程编程

class SingleTon
{
    
    
public:
	static SingleTon* getInstance()
	{
    
    
			if (psing == NULL)
			{
    
    
				psing = new SingleTon();
			}
		}
		return psing;
	}
private:
	SingleTon(){
    
    }
	SingleTon(const SingleTon&);
	static SingleTon* psing;
};
SingleTon* SingleTon::psing = NULL;

测试样例:

	SingleTon* psing1 = SingleTon::getInstance();
	SingleTon* psing2 = SingleTon::getInstance();
	SingleTon* psing3 = SingleTon::getInstance();
	SingleTon* psing4 = SingleTon::getInstance();

调试结果:

在这里插入图片描述
bug:
延时加载只有在instance等于NULL时才创建,如果处于多线程环境,当未创建对象时另一线程也执行到相同阶段,程序就会出现问题。所以,我们可以给 程序加锁

class SingleTon
{
    
    
public:
	static SingleTon* getInstance()
	{
    
    
			lock();
			if (psing == NULL)
			{
    
    
				psing = new SingleTon();
			}
			unlock();
		}
		return psing;
	}
private:
	SingleTon(){
    
    }
	SingleTon(const SingleTon&);
	static SingleTon* psing;
};
SingleTon* SingleTon::psing = NULL;

可以看见,上述程序给if(psing == NULL) 的两边进行了lock()和unlock()操作

为什么要有加锁解锁操作?

多线程访问共享资源时,为防止产生脏数据和错误而采取的方式。多线程访问同一个数据库时,数据库是共享资源,所以对库操作要加锁。程序也是这个道理。
举例:1个厕所不能提供多人用,进入厕所加锁,使用完解锁。

上述程序当对象创建出来之后,还是会反复执行加锁解锁,占用 内存,降低效率。
所以 ,基于上边的程序,提出了双重锁机制
二、双重锁机制

所谓双重锁,就是在加锁之前判断对象是否已经创建成功,如果ture,就不执行加锁解锁操作。反之,执行此操作;

class SingleTon
{
    
    
public:
	static SingleTon* getInstance()
	{
    
    
		if (psing == NULL)//没有命中  对象已经生成
		{
    
    
			lock();
			if (psing == NULL)
			{
    
    
				psing = new SingleTon();
			}
			unlock();
		}
		return psing;
	}
private:
	SingleTon(){
    
    }
	SingleTon(const SingleTon&);
	static SingleTon* psing;
};
SingleTon* SingleTon::psing = NULL;

三、贪婪加载

所谓贪婪加载,就是提前创建对象,利用静态全局变量,直接构建实例,并将静态指针指向同一内存块;

class SingleTon
{
    
    
public:
	static SingleTon* getInstance()
	{
    
    
		return psing;
	}
private:
	SingleTon(){
    
    }
	SingleTon(const SingleTon&);
	static SingleTon* psing;
};
SingleTon* SingleTon::psing = new SingleTon();

经过调试可以看见无论如何调用psing方法,都只有一个实例产生,这就实现了C++中的单例模式。

猜你喜欢

转载自blog.csdn.net/Gunanhuai/article/details/103019383