设计模式学习(一) 单例模式 Singleton

1. 单例模式的定义:

单例模式属于创建者模式,顾名思义,即保证为一个类只生成唯一的实例对象。其结构可以简单粗暴地用以下类图来表示:
单例的类图
由其类图可见,单例的成员仅有类型为其自身Singleton的参数Instance,而方法为构造函数和单例实现函数GetInstance()。其中GetInstance为静态方法,主要负责创建自己的唯一实例(在创建完成之后,返回所创建的自己)

2. 单例模式的使用情况

单例模式主要就是用于当且仅当该对象只能创建出一个时,必须保证该对象是唯一时的情况,或者需要创建一个共同体来共享资源时。

3. 单例模式的分类以及代码实现

3.1 懒汉式

只有在获取单例时(调用GetInstance()函数时),才会new出单例的对象,其具体的代码如下:

class Singleton     //单例模式懒汉式,当其被获取单例时(GetInstance时),才会对单例进行NEW操作
{
public:
	Singleton() { cout << "懒汉构造函数执行" << endl; }
	static Singleton* GetInstance()
	{
		if (m_sig == nullptr)
		{
			m_sig = new Singleton();
			cout << "懒汉单例实现" << endl;
		}
		return m_sig;
	}
	void Free()
	{
		if (m_sig != nullptr)
		{
			delete m_sig;
			m_sig = nullptr;
		}
		cout << "懒汉析构执行" << endl;
	}
private:
	static Singleton* m_sig;
};

Singleton* Singleton::m_sig = nullptr;    //类外定义初始值

这里值得一提的是,懒汉式的内部对象m_sig是静态对象,其初始值nullptr的定义在类外进行。

3.2 饿汉式

饿汉式单例即在函数开始初始化的阶段,直接在全局变量区就new出了单例对象。即在开始执行main函数前就已经定义了单例。其具体代码如下:

class Singleton_Ehan     //单例模式饿汉式,其内部静态变量在创建时即NEW出,不需要在被获取时创建
{
public:
	Singleton_Ehan() { cout << "饿汉构造函数执行" << endl; }
	static Singleton_Ehan* GetInstance()
	{
		return m_esig;
	}
	void Free()
	{ 
		if (m_esig != nullptr)
		{
			delete m_esig;
			m_esig = nullptr;
		}
		cout << "饿汉析构执行" << endl; 
	}
private:
	static Singleton_Ehan* m_esig;
};

Singleton_Ehan* Singleton_Ehan::m_esig = new Singleton_Ehan();    //类外直接赋值

这里指的一提的是,饿汉式的静态变量在初始化时就直接new出来了,而不是懒汉式那样还需要调用GetInstance函数。同时不同的还有n调用GetInstance函数时,懒汉式是先new再return,而饿汉式由于已经提前定义了就直接return了。

3.3 测试时使用的主函数

int main_singleton()
{
	Singleton* temp1 = Singleton::GetInstance();
	Singleton* temp2 = Singleton::GetInstance();

	Singleton_Ehan* temp3 = Singleton_Ehan::GetInstance();
	Singleton_Ehan* temp4 = Singleton_Ehan::GetInstance();

	if (temp1 == temp2)
		cout << "懒汉相同" << endl;
	else
		cout << "懒汉不相同" << endl;

	if (temp3 == temp4)
		cout << "饿汉相同" << endl;
	else
		cout << "饿汉不相同" << endl;

	temp1->Free();
	temp2->Free();
	temp3->Free();
	temp4->Free();

	return 0;
}

4. 单例模式的一些问题

目前我所已知的问题,就是懒汉式在面对多线程情况下的“失效”问题:
由于懒汉式的new的过程发生在调用GetInstance函数的过程中,而函数的执行是需要一定的时间的,所以当多个线程同时执行懒汉式的单例GetInstance函数时,可能会导致new出多个类的情况发生,这是与单例模式的本例相违背的。
目前具体的解决方式即为线程同步的方式,其中最为常用的即为lock+unlock这样的互斥量连锁控制方式,可以保证new的这段代码有且只能让一个线程在使用,从而从根本上避免这种“乌龙”的情况产生。

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

方寸间沧海桑田

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值