设计模式之单例模式(singleton)

单例模式用来创建独一无二的对象。单例模式的对象只能有一个实例。有些对象我们只需要一个,比如,线程池、缓存、对话框、日志对象,充当打印机、显卡等设备的驱动程序的对象。事实上,这类对象只能有一个实例,如果实例化黑多个这类对象,就可能会导致其他问题的产生。因此单例模式的应用很广泛。

单例模式在head first 给出的定义是 :确保一个类只有一个实例,并提供一个全局访问点。

单例模式的要点有三个:1 类只有一个实例  2 类定义中含有一个该类的私有对象  3 提供静态成员函数来创建或者获取其本身的私有静态对象。  

单例模式是所有模式中最为简单的。单例模式的实现方式有很多种。如下所示:

//Singleton Patterns one
class SingletonOne
{
private:
	static SingletonOne m_instance;
	SingletonOne()
	{
		std::cout << "SingletonOne::constructor()" << std::endl;
	}
	~SingletonOne()
	{
		std::cout << "SingletonOne::destructor()" << std::endl;
	}

public:
	static SingletonOne* GetInstance()
	{
		return &m_instance;
	}
	void Initialize()
	{
		std::cout << "SingletonOne::Initialize()" << std::endl;
	}
	void Add()
	{
		std::cout << "SingletonOne :: Add()" << std::endl;
	}
};

/*
 * Singleton Patterns two 
 * must explicit call destructor
 */  
class SingletonTwo
{
private:
	static SingletonTwo *m_instance;
	SingletonTwo()
	{
		std::cout << "SingletonTwo::constructor()" << std::endl;
	}
	~SingletonTwo()
	{
		std::cout << "SingletonTwo::destructor()" << std::endl;
	}
public:
	static SingletonTwo* GetInstance()
	{
		if (m_instance == nullptr)
		{
			m_instance = new SingletonTwo();
		}
		
		return m_instance;
	}
	void Initialize()
	{
		std::cout << "SingletonTwo::Initialize()" << std::endl;
	}
	void Add()
	{
		std::cout << "SingletonTwo::Add()" << std::endl;
	}
};

/*
* Singleton Patterns three
* must explicit call destructor
*/
class SingletonThree
{
private:
	SingletonThree()
	{
		std::cout << "SingletonThree::constructor()" << std::endl;
	}
	~SingletonThree()
	{
		std::cout << "SingletonThree::destructor()" << std::endl;
	}
public:
	static SingletonThree* GetInstance()
	{
		static SingletonThree m_instance;
		return &m_instance;
	}
	void Initialize()
	{
		std::cout << "SingletonThree::Initialize()" << std::endl;
	}
	void Add()
	{
		std::cout << "SingletonThree::Add()" << std::endl;
	}
};
 调用单例模式的测试代码:

#include<windows.h>
#include<iostream>

#include"singleton.h"

SingletonOne SingletonOne::m_instance;
SingletonTwo* SingletonTwo::m_instance;

int main()
{
	std::cout << "******* < 1 > SingletonOne Test*******" << std::endl;
	SingletonOne *one = SingletonOne::GetInstance();
	one->Initialize();
	SingletonOne::GetInstance()->Add();

	std::cout << "******* < 1 > SingletonOne Test*******\n\n\n\n\n" << std::endl;
	
	// when doos this version to destructor
	std::cout << "******* < 2 > SingletonTwo Test*******" << std::endl;
	SingletonTwo *two = SingletonTwo::GetInstance();
	two->Initialize();
	SingletonTwo::GetInstance()->Add();
	
	std::cout << "******* < 2 > SingletonTwo Test*******\n\n\n\n\n" << std::endl;
	

	std::cout << "******* < 3 > SingletonTwo Test*******" << std::endl;
	
	SingletonThree *three = SingletonThree::GetInstance();
	three->Initialize();
	SingletonThree::GetInstance()->Add();

	std::cout << "******* < 3 > SingletonThree Test*******\n\n\n\n\n" << std::endl;

//	system("pause");
	
	return 0;
}

上面使用三种方式分别实现了单例模式。通过显式编写构造函数和析构函数,可以让我们对单例模式的构造‘、析构有更为深刻的了解。


单例模式虽然很简单,但需要处理多线程情况下出现多个实例的情况。比如,当一个线程判断实例为空时,还没创建实例时,系统就把CPU使用权交给另外一个线程,第二个线程判断没有实例,会创建一个实例,当操作系统将CPU使用权再次分配给线程一是就会创建第二个实例,引发线程灾难。只要把GetInstance()方法变成同步。多线程灾难即可迎刃而解。可以通过加锁的方式解决。这里就不在列出实例代码。




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值