シングルトンパターンクラス設計|ハングリーマンモードと怠け者モードとは

序文

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

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

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


シングルトンパターンとは

クラスはオブジェクトを 1 つだけ作成できます。つまり、シングルトン モードでは、システム内にクラスのインスタンスが 1 つだけ存在することが保証され、それにアクセスするためのグローバル アクセス ポイントが提供され、すべてのプログラム モジュールで共有されます。たとえば、サーバー プログラムでは、サーバーの構成情報がファイルに保存され、これらの構成データがシングルトン オブジェクトによって均一に読み取られ、サービス プロセス内の他のオブジェクトがこのシングルトン オブジェクトを通じて構成情報を取得します。このアプローチにより、複雑な環境での構成管理が簡素化されます。

シングルトン パターンには 2 つの実装があります。

  • 飢えた男モード
  • レイジーモード

飢えた男モード

つまり、今後使用するかどうかに関係なく、プログラムの開始時に一意のインスタンス オブジェクトが作成されます

アドバンテージ:

  • シンプルでスレッドの安全性の問題はありません

欠点:

  • プログラム内に複数のシングルトンがあり、初期化の順序に要件がある場合、飢えた人はそれを制御できません。
  • 作成されたシングルトン クラスや初期化タスクが多すぎると、プログラムの起動速度に影響します。
//设计只能创建一个对象的类(单例模式)
//有两种设计方案
//饿汉模式 -- 一开始(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

レイジーモード

オブジェクトは、初めて使用するときに作成されます。

アドバンテージ:

  • 順序はコントロールできる
  • 起動速度には影響しません

欠点:

  • 比較的複雑な
  • スレッドの安全性の問題は適切に処理する必要があります
//懒汉模式
//对象第一次使用的时候再创建
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;
}

シングルトンモードの解放問題

  • 一般に、シングルトン オブジェクトは解放する必要はありません。通常、シングルトン オブジェクトはプログラムの実行時間全体にわたって使用されます。シングルトン オブジェクトは、プロセスが正常に終了した後もリソースを解放します。
  • いくつかの特別なシナリオをリリースする必要があります。たとえば、シングルトン オブジェクトが破棄された場合、いくつかの永続化操作 (ファイルやデータベースへの書き込み) が必要になります。大きなアイデア: 内部ガベージ コレクション クラスを定義する

Supongo que te gusta

Origin blog.csdn.net/Yu_Cblog/article/details/131787131
Recomendado
Clasificación