Singleton pattern class design|What is the hungry man mode and the lazy man mode

foreword

那么这里博主先安利一些干货满满的专栏了!

首先是博主的高质量博客的汇总,这个专栏里面的博客,都是博主最最用心写的一部分,干货满满,希望对大家有帮助。

高质量干货博客汇总https://blog.csdn.net/yu_cblog/category_12379430.html?spm=1001.2014.3001.5482


What is a singleton pattern

A class can only create one object, that is, the singleton mode, which can ensure that there is only one instance of the class in the system, and provide a global access point to access it, which is shared by all program modules. For example, in a server program, the configuration information of the server is stored in a file, and these configuration data are uniformly read by a singleton object, and then other objects in the service process obtain the configuration information through this singleton object, which is This approach simplifies configuration management in complex environments.

There are two implementations of the singleton pattern:

  • hungry man mode
  • lazy mode

hungry man mode

That is to say, whether you use it in the future or not, a unique instance object is created when the program starts .

advantage:

  • Simple, no thread safety issues

shortcoming:

  • When there are multiple singletons in a program and there is a requirement for the order of initialization, the hungry man cannot control it.
  • When there are too many singleton classes created and too many initialization tasks, the startup speed of the program will be affected.
//设计只能创建一个对象的类(单例模式)
//有两种设计方案
//饿汉模式 -- 一开始(main())之前就创建出对象了
#if 1
class MemoryPool //假设要求设计一个内存池 -- 要求是单例的 ,当然只是名字而已,我们不是真的实现内存池
{
public:
	static MemoryPool* GetInstance()
	{
		return _pinst;
	}
	void* Alloc(size_t n)
	{
		void* ptr = nullptr;
		//...
		//里面啥东西我们不管
		return ptr;
	}
	void Dealloc(void* ptr)
	{
		//...
	}
protected:
	char* _ptr = nullptr;
protected:
	//构造函数私有
	MemoryPool() {}
	//两种写法,这里只写了一种,写成指针也可以,不写成指针也可以
	static MemoryPool* _pinst;//声明
};
MemoryPool* MemoryPool::_pinst = new MemoryPool;


#define MemoryPoolObject MemoryPool::GetInstance()
int main()
{
	//一般是这样调用的,直接调就行
	void* ptr1 = MemoryPool::GetInstance()->Alloc(10);
	MemoryPool::GetInstance()->Dealloc(ptr1);
	//单例模式一般就是通过这个 MemoryPool::GetInstance() 去找到这个已经创建好的对象,去调它里面的东西
	void* ptr2 = MemoryPoolObject->Alloc(29);
	MemoryPoolObject->Dealloc(ptr2);
	return 0;
}
#endif

lazy mode

The object is created when it is used for the first time.

advantage:

  • order can be controlled
  • does not affect startup speed

shortcoming:

  • relatively complex
  • Thread safety issues should be handled well
//懒汉模式
//对象第一次使用的时候再创建
class MemoryPool //假设要求设计一个内存池 -- 要求是单例的 ,当然只是名字而已,我们不是真的实现内存池
{
public:
	static MemoryPool* GetInstance()
	{
		//如果发现指针是nullptr的时候,说明我们是第一次使用这个类
		if (_pinst == nullptr)
		{
			//第一次创建
			cout << "第一次创建对象" << endl;
			_pinst = new MemoryPool;
		}
		return _pinst;
	}
	void* Alloc(size_t n)
	{
		void* ptr = nullptr;
		//...
		//里面啥东西我们不管
		return ptr;
	}
	void Dealloc(void* ptr)
	{
		//...
	}
	class CGarbo
	{
	public:
		~CGarbo()
		{
			if (_pinst)delete _pinst;
		}
	};
protected:
	char* _ptr = nullptr;
protected:
	//构造函数私有
	MemoryPool() {}
	//两种写法,这里只写了一种,写成指针也可以,不写成指针也可以
	static MemoryPool* _pinst;//声明
};
MemoryPool* MemoryPool::_pinst = nullptr;
//回收对象
//在main结束之后,它会调用析构函数,就会释放单例对象
static MemoryPool::CGarbo gc;
#define MemoryPoolObject MemoryPool::GetInstance()
int main()
{
	//一般是这样调用的,直接调就行
	cout << " -------- 第一次使用 -------- " << endl;
	void* ptr1 = MemoryPool::GetInstance()->Alloc(10);
	MemoryPool::GetInstance()->Dealloc(ptr1);
	//单例模式一般就是通过这个 MemoryPool::GetInstance() 去找到这个已经创建好的对象,去调它里面的东西
	cout << " -------- 第二次使用 -------- " << endl;
	void* ptr2 = MemoryPoolObject->Alloc(29);
	MemoryPoolObject->Dealloc(ptr2);
	return 0;
}

The release problem of singleton mode

  • In general, a singleton object does not need to be released -- generally it will be used throughout the runtime of the program. The singleton object will also release resources after the process ends normally.
  • Some special scenarios need to be released. For example, when a singleton object is destructed, some persistence operations (writing to files and databases) are required. The big idea: define an internal garbage collection class

Guess you like

Origin blog.csdn.net/Yu_Cblog/article/details/131787131