シングルトンモード
別名:シングルモード、シングルトン
シングルトンパターンは、クラスのインスタンスが1つだけであることを確認し、そのインスタンスにアクセスするためのグローバルノードを提供できるようにする創造的なデザインパターンです。
問題
シングルトンモードは2つの問題を同時に解決するため、_単一責任の原則_に違反します。
1.クラスのインスタンスが1つだけであることを確認します。
2.インスタンスにグローバルアクセスノードを提供します
解決
すべてのシングルトンの実現には、次の2つの同一のステップが含まれます。
- 単一クラスの実施形態
new
演算子を使用する他のオブジェクトを防ぐために、デフォルトのコンストラクターはプライベートです。 - コンストラクターとして新しい静的構築メソッドを作成します。この関数は、プライベートコンストラクターを「密かに」呼び出してオブジェクトを作成し、静的メンバー変数に保存します。この関数への後続のすべての呼び出しは、このキャッシュオブジェクトを返します。
コードがシングルトンクラスにアクセスできる場合は、シングルトンクラスの静的メソッドを呼び出すことができます。このメソッドが呼び出されるたびに、常に同じオブジェクトが返されます。
シングルトンモードは、アプリケーションシナリオに適しています
プログラム内の特定のクラスで、すべてのクライアントが使用できるインスタンスが1つしかない場合は、シングルトンモードを使用できます。
シングルトンモードでは、特別な構築方法以外の方法で独自のクラスのオブジェクトを作成することは禁止されています。このメソッドは新しいオブジェクトを作成できますが、オブジェクトがすでに作成されている場合は、既存のオブジェクトを返します。
グローバル変数をより厳密に制御する必要がある場合は、シングルトンモードを使用できます。
シングルトンモードは、クラスのインスタンスが1つだけであることを保証するという点でグローバル変数とは異なります。シングルトンクラス自体を除いて、キャッシュされたインスタンスを置き換えることはできません。
実施形態の例の制限数生成単位はいつでも調整および設定できることに留意されたい。変更获取实例
方法、すなわち、getInstartコードのみを実現することができる。
実現する方法
- プライベート静的メンバー変数をクラスに追加して、シングルトンインスタンスを保存します。
- シングルトンインスタンスを取得するためのパブリック静的構築メソッドを宣言します。
- 静的メソッドに「遅延初期化」を実装します。このメソッドは、最初に呼び出されたときに新しいオブジェクトを作成し、静的メンバー変数に格納します。その後、メソッドは呼び出されるたびにこのインスタンスを返します。
- クラスのコンストラクターをプライベートにします。クラスの静的メソッドは引き続きコンストラクターを呼び出すことができますが、他のオブジェクトはそれを呼び出すことができません。
- クライアントコードを確認し、シングルトンのコンストラクターの呼び出しを静的構築メソッドの呼び出しに置き換えます。
実装例-レイジーマンモード(ロック判定)
#include <iostream>
#include <mutex>
using namespace std;
class HttpServer
{
public :
static HttpServer *getInstance()
{
if (instance == nullptr)
{
/* 当第一个线程执行到此,对locker对象 "加锁",
当第二个线程执行到此,如果检测到locker对象为"加锁"状态,该线程就会挂起等待第一个线程解锁后再继续执行
lock语句执行完也即代表上一个线程执行结束,同时对该对象"解锁"
*/
std::unique_lock<std::mutex> lock(m_mutex);
if (instance == nullptr)
{
instance = new HttpServer();
}
}
return instance;
}
private:
static HttpServer *instance; 定义一个用于保存静态变量的实例
static std::mutex m_mutex;
HttpServer() {
} //构造函数
HttpServer(const HttpServer &) = delete; //默认拷贝构造
~HttpServer() {
} //析构函数
};
HttpServer *HttpServer::instance = nullptr;
std::mutex HttpServer::m_mutex;
int main()
{
HttpServer *t1 = HttpServer::getInstance();
HttpServer *t2 = HttpServer::getInstance();
cout << t1 << " " << t2 << endl;
return 0;
}
結果
0x2216e70 0x2216e70 //相同的地址
実装例-空腹の人モード(初期化中に構築)
#include <iostream>
#include <mutex>
using namespace std;
class HttpServer
{
public :
static HttpServer *getInstance()
{
return instance;
}
private:
static HttpServer *instance; 定义一个用于保存静态变量的实例
static std::mutex m_mutex;
HttpServer() {
} //构造函数
HttpServer(const HttpServer &) = delete; //默认拷贝构造
~HttpServer() {
} //析构函数
};
HttpServer *HttpServer::instance = new HttpServer();
std::mutex HttpServer::m_mutex;
int main()
{
HttpServer *t1 = HttpServer::getInstance();
HttpServer *t2 = HttpServer::getInstance();
if (t1 == t2)
{
cout<<("Singleton works, both variables contain the same instance.")<< endl;
}
else
{
cout<<("Singleton failed, variables contain different instances.")<< endl;
}
return 0;
}
結果
Singleton works, both variables contain the same instance.