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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/w_x_myself/article/details/82113538

1、定义

单例模式(Singleton Pattern)是最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

2、介绍

优点: 1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。 2、避免对资源的多重占用(比如写文件操作)。

缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。

使用场景: 1、要求生产唯一序列号。 2、WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。 3、创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。

注意事项:getInstance() 方法中需要使用同步锁 synchronized (Singleton.class) 防止多线程同时进入造成 instance 被多次实例化。

3、源码

思路:1、在类中,定义静态成员变量和静态成员函数,通过静态成员函数对静态成员进行复制,定义新对象时可以保证类的构造函数只会被调用一次。2、将构造函数私有化,防止创建新的实例。

3.1、头文件

Emperor.h

#pragma once
#include <Windows.h>
#include <winnt.h>
#include <iostream>
using namespace std;
class Emperor
{
public:
	static Emperor* getInstance();
	static void releaseInstance();
	void emperorInfo(void);
	void setEmperorTag(string tag);
	
private:
	Emperor(void);
	virtual ~Emperor(void);
	Emperor(const Emperor&);
	Emperor& operator=(const Emperor&);
	static Emperor *m_emperor;
	static HANDLE m_mutex;
	string m_emperor_tag;
	class Garbo
	{
	public:
		Garbo()
		{
			cout << "create garbo" << endl;
		}
		~Garbo()
		{
			cout << "destrory garbo" << endl;
			getchar();
			if (NULL != m_emperor)
			{
				WaitForSingleObject(m_mutex, INFINITE);
				if (NULL != m_emperor)
				{
					cout << "remove instance" << endl;
					delete m_emperor;
					m_emperor = NULL;
				}
				ReleaseMutex(m_mutex);
			}
			if (NULL != m_mutex)
			{
				cout << "delete mutex" << endl;
				CloseHandle(m_mutex);
				m_mutex = NULL;
			}
		}
	};
	static Garbo m_garbo;
};

3.2、实现文件

Empeor.h

#include "Emperor.h"
#include <iostream>
Emperor *Emperor::m_emperor = NULL;
HANDLE Emperor::m_mutex = CreateMutex(NULL, FALSE, NULL);
Emperor::Garbo Emperor::m_garbo;
Emperor::Emperor(void)
{
	cout << "create emperor instance" << endl;
}
Emperor::~Emperor(void)
{
	cout << "destroy emperor instance and release its resources" << endl;
}
void Emperor::emperorInfo(void)
{
	char msg_buf[50] = { 0 };
	sprintf_s(msg_buf, 50, "the emperor's name is (%s)", m_emperor_tag.c_str());
	string msg(msg_buf);
	cout << msg.c_str() << endl;
}
Emperor *Emperor::getInstance()
{
	if (NULL == m_emperor)
	{
		WaitForSingleObject(m_mutex, INFINITE);
		if (NULL == m_emperor)
			m_emperor = new Emperor();
		ReleaseMutex(m_mutex);
	}
	return m_emperor;
}
void Emperor::releaseInstance()
{
	if (NULL != m_emperor)
	{
		WaitForSingleObject(m_mutex, INFINITE);
		if (NULL != m_emperor)
		{
			delete m_emperor;
			m_emperor = NULL;
		}
		ReleaseMutex(m_mutex);
	}
}
void Emperor::setEmperorTag(string tag)
{
	m_emperor_tag = tag;
}

main.cpp

#include "Emperor.h"
int main()
{
	
	Emperor *pEmperor1 = Emperor::getInstance();
	pEmperor1->setEmperorTag("QL");
	pEmperor1->emperorInfo();
	Emperor *pEmperor2 = Emperor::getInstance();
	pEmperor2->emperorInfo();
	Emperor *pEmperor3 = Emperor::getInstance();
	pEmperor3->emperorInfo();
	
	Emperor::releaseInstance();
	system("pause");
	return 0;
}

4、结果显示

参考文献:《菜鸟教程》   https://blog.csdn.net/phiall/article/details/52199659博客

猜你喜欢

转载自blog.csdn.net/w_x_myself/article/details/82113538