シングルトンパターン
前書き
シングルトンパターン(シングルトンパターン、シングルトンパターンとも呼ばれます)は、非常に広く使用されているデザインパターンです。その目的は、クラスの特定のプログラムにインスタンスが1つしかないことを確認し、グローバルアクセスインターフェイスを提供することです。つまり、インスタンスはプログラムによって共有されます。
シングルトンパターンのクラス図:
シングルトンモードの機能:
1.コンストラクターを
プライベート化して、外部がクラスのインスタンスを作成しないようにします。2。クラスのプライベート静的変数ポインターを使用して、クラスの唯一のインスタンスをポイントします
。3。共通の静的メソッドを使用して、クラスのインスタンスを取得します。
シングルトンモードの実装
1.空腹の中国人
空腹のチャイニーズスタイルとは何ですか?つまり、通常の状況では、プログラムの初期化時にオブジェクトがインスタンス化されています。後で使用するために初期化する必要はありません。
class Singleton
{
private:
static Singleton* instance;
private:
Singleton() {};
~Singleton() {};
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
public:
static Singleton* getInstance()
{
return instance;
}
};
//initialize defaultly
Singleton* Singleton::instance = new Singleton();
空腹スタイルのシングルトンオブジェクトは、実際にはプログラムのメイン関数の前に初期化されるため、スレッドの安全性の問題はありません。
2.怠惰な男
怠惰な男は何ですか?つまり、通常の状況では、オブジェクトを使用する必要があるときに、オブジェクトを初期化します(つまり、最初に使用したときに初期化されます)。
class Singleton
{
private:
static Singleton* instance;
private:
Singleton() {};
~Singleton() {};
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
public:
static Singleton* getInstance()
{
if(instance == NULL)
instance = new Singleton();
return instance;
}
};
// init static member
Singleton* Singleton::instance = NULL;
3.スレッドセーフな方法
マルチスレッドを使用する場合、怠惰な方法を使用してシングルトンを実装すると、スレッドが安全でない状況が発生します。2つのスレッドがあるとすると、pthread_1は、インスタンスがNULLであると判断したばかりであり、インスタンスの作成を準備するときに、 pthread_2に切り替えると、この時点でpthread_2は、インスタンスがtrueであると判断し、インスタンスを作成し、pthread_1に戻ったときに戻るインスタンスを作成し続けると、現時点ではシングルトンモードの要件が満たされなくなります。この場合、はいマルチスレッドアクセスの問題があるため、スレッドを同期するためのロックを追加します。
class Singleton
{
private:
static Singleton* instance;
static pthread_mutex_t mutex;
private:
Singleton() {};
~Singleton() {};
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
public:
static Singleton* getInstance()
{
if (NULL == instance ){
pthread_mutex_lock(&mutex)
if(instance == NULL)
instance = new Singleton();
pthread_mutex_unlock(&mutex)
}
return instance;
}
};
pthread_mutex_t singleton::mutex;
// init static member
Singleton* Singleton::instance = NULL;
4.一般的な編集方法
template <typename T>
class Singleton {
public:
static T* GetInstance(){
static std::once_flag s_flag;
std::call_once(s_flag, [&](){
singleton_ptr.reset(new T);
});
return singleton_ptr.get();
}
protected:
Singleton(){};
~Singleton(){};
private:
static std::shared_ptr<T> singleton_ptr;
Singleton(const Singleton&) = delete;
Singleton&operator=(const Singleton&) = delete;
}; // end singleton
template<typename T> std::shared_ptr<T> Singleton<T>::singleton_ptr;
このメソッドは、std :: shared_ptr、std :: once_flag、std :: call_onceなどのC11の知識を使用します。このメソッドの利点は、プログラムが異なるタイプの複数のシングルトンオブジェクトを必要とする場合です。 、対応するメソッドを実装する必要はありません。クラスを直接継承するだけです。次のように:
class TestClass: public Singleton<TestClass> {
public:
TestClass();
~TestClass();
};
機会を利用する
- システムに必要なインスタンスオブジェクトは1つだけです。または、リソースの消費量が多すぎることを考慮すると、作成できるオブジェクトは1つだけです。
- クライアント呼び出しクラスの単一のインスタンスは、1つのパブリックアクセスポイントのみを使用でき、他の手段(つまり、一般的な静的メソッド)によるインスタンスへのアクセスは、このアクセスポイント以外は許可されません。