C++的单例模式设计

单例模式:使类只能生成一个对象。

我们可以想一下如何能限制类生成对象的个数呢?我们知道一个对象的生成至少要两步,开辟内存,调用构造函数。我们没有办法限制内存的开辟,但我们可以控制构造函数的调用情况,沿着这个思路我们得出单例模式的设计思路:

  • 先屏蔽对象生成的接口,即控制构造函数,我们将构造函数设为私有的,让其不能在类外调用。故将构造函数和拷贝构造函数设为私有的是第一步。
  • 我们要提供一个共有的接口来生成唯一的对象,我们在设计这个函数时要满足两点,1.不能以类类型返回,因为类类型返回会生成一个临时对象,那么我们就有两个对象了,所以不行,我们可以在类指针和类引用任选一个。2.接口要摆脱对对象的依赖,否则第一个对象永远无法生成,所以将其设为静态的,静态的不属于对象,它可以由类调用。
  • 这个接口会被调用很多次,所以我们要保证他被调了很多次但只生成一个对象,故我峨嵋你设置一个静态成员变量来保存唯一的一个类,每次在调用时进行判断,若为第一次调用则生成类,若为第二次调用则直接返回类。

那我们现在根据这个思路写个一个简单的单例模式的类:

# include <iostream>
class master
{
private:
	master (char* name,bool sex)//构造函数
	{
		mname=new char[strlen(name+1)]();
		strcpy(mname,name);
		msex=sex;
	}
	master(const master&)//拷贝构造
	{}
	char *mname;
	bool msex;
	static master *pinstance;//静态成员变量,保存一个对象的地址
public:
	static master* getinstance(char* name,bool sex)//公共的接口
	{
		if(pinstance==NULL)//第一次则生成对象
		{
			pinstance=new master(name,sex);
		}
		return pinstance;//不是第一次则直接返回第一次生成的对象地址
	}
	void show()
	{
		std::cout<<"生成的对象名字为"<<mname<<std::endl;
	}
};
master* master::pinstance=NULL;//初始化静态成员
int main()
{
	master *pm1=master::getinstance("王麻子", true);//定义对象指针保存对象的地址
	master *pm2=master::getinstance("李四", true);
	master *pm3 = master::getinstance("王五", true);
	pm1->show();
	pm2->show();
	pm3->show();
}

我们可以看到在主函数里面我们申请了3个对象,那么程序是否会为我们生成三个对象呢,还是只有一个对象呢,我们通过打印函数来查看,运行结果如下图:

我们可以看到系统只为我们生成了第一个对象,王麻子,其他的对象生成时程序直接返回王麻子的地址,所以实现了单例模式。但是我们可以看到它是不安全的程序,并且效率低,我们把这种用的时候再生成对象的单例模式称为懒汉模式,又称为延时加载,它是一种线程不安全的模式。

那么大家肯定会想到能不能有一种安全模式来实现单例模式呢,当然有了,下面我为大家介绍以下饿汉模式,又称为贪婪加载,相信大家看名字就知道啥意思了吧,没错它就是防患于未然,提前就生成一个对象,在main之前对象就会生成,这样就不会出现线程不安全了。具体代码如下:

# include <iostream>
class master
{
private:
	master (char* name,bool sex)//构造函数
	{
		mname=new char[strlen(name+1)]();
		strcpy(mname,name);
		msex=sex;
	}
	master(const master&)//拷贝构造
	{}
	char *mname;
	bool msex;
	static master *pinstance;//静态成员变量,保存一个对象的地址
public:
	static master* getinstance(char* name,bool sex)//公共的接口
	{
		return pinstance;//直接返回已经生成的对象地址,保证只有一个对象
	}
	void show()
	{
		std::cout<<"生成的对象名字为"<<mname<<std::endl;
	}
};
master* master::pinstance=new master("王麻子",true);//在主函数之前就已经申请好了对象,所以只会有王麻子这一个对象
int main()
{
	master *pm1=master::getinstance("张三", true);//定义对象指针保存对象的地址
	master *pm2=master::getinstance("李四", true);
	master *pm3 = master::getinstance("王五", true);
	pm1->show();
	pm2->show();
	pm3->show();
}

我们可以看到,在给保存唯一一个对象的静态成员变量初始化时我们就已经让它生成王麻子这一个对象了,所以它是在主函数之前就生成了,故无论你在主函数里面定义几个对象,它都不会生成,你每次在申请时都只返回王麻子找个对象的地址,我们来看结果: 

单例模式的设计就到这,若有错误请大家指出哦!加油哦?‍♀️

发布了54 篇原创文章 · 获赞 8 · 访问量 5323

猜你喜欢

转载自blog.csdn.net/qq_43411555/article/details/90341421
今日推荐