C++
シングルトンデザインパターン
サーチ…
備考
シングルトンは、クラスがインスタンスを1つだけ有し、それへのアクセスのグローバルポイントを提供するように設計されています。 1つのインスタンスまたは便利なグローバル・アクセス・ポイントのみを必要とし、両方のアクセス・ポイントを必要としない場合は、シングルトンに切り替える前に他のオプションを検討してください。
グローバル変数は 、コードを推論するのをより困難にする可能性があります。たとえば、呼び出し関数の1つがシングルトンから受け取ったデータに満足していない場合は、最初にシングルトンの不良データを最初に与えるものを追跡する必要があります。
シングルトンはまた結合を促進します。これは結合されたコードの2つのコンポーネントを記述するために使用される用語で、各コンポーネントは自己包含の独自の測定を減らします。
シングルトンは並行性に劣ります。クラスにグローバル・アクセス・ポイントがある場合、すべてのスレッドはそれにアクセスでき、デッドロックや競合状態に陥る可能性があります。
最後に、怠惰な初期化は、間違った時刻に初期化された場合、パフォーマンスの問題を引き起こす可能性があります。遅延初期化を削除することで、多態性(サブクラスを参照)などのシングルトンの興味深い機能を削除することもできます。
レイジー初期化
この例はここのQ & A
セクションから削除されました: http : //stackoverflow.com/a/1008289/3807729
保証された破壊シングルトンで評価された遅延評価用の簡単な設計については、この記事を参照してください。
誰でも私にシングルトンのサンプルをc ++で提供できますか?
古典的な怠け者は評価され、正しくシングルトンを破壊しました。
class S
{
public:
static S& getInstance()
{
static S instance; // Guaranteed to be destroyed.
// Instantiated on first use.
return instance;
}
private:
S() {}; // Constructor? (the {} brackets) are needed here.
// C++ 03
// ========
// Dont forget to declare these two. You want to make sure they
// are unacceptable otherwise you may accidentally get copies of
// your singleton appearing.
S(S const&); // Don't Implement
void operator=(S const&); // Don't implement
// C++ 11
// =======
// We can use the better technique of deleting the methods
// we don't want.
public:
S(S const&) = delete;
void operator=(S const&) = delete;
// Note: Scott Meyers mentions in his Effective Modern
// C++ book, that deleted functions should generally
// be public as it results in better error messages
// due to the compilers behavior to check accessibility
// before deleted status
};
シングルトンを使用する時期については、この記事を参照してください(頻繁ではありません)
シングルトン:どのように使うべきか
初期化の順序と対処方法については、次の2つの記事を参照してください。
静的変数の初期化順序
C ++の静的初期化順序問題の発見
ライフタイムを説明するこの記事をご覧ください:
C ++関数の静的変数の存続期間は何ですか?
シングルトンに対するいくつかのスレッドの影響を説明しているこの記事を参照してください。
GetInstanceメソッドの静的変数として宣言されたシングルトンインスタンス
C ++でダブルチェックロックが機能しない理由を説明しているこの記事を参照してください。
C ++プログラマが知るべき共通の未定義の振る舞いは何ですか?
サブクラス
class API
{
public:
static API& instance();
virtual ~API() {}
virtual const char* func1() = 0;
virtual void func2() = 0;
protected:
API() {}
API(const API&) = delete;
API& operator=(const API&) = delete;
};
class WindowsAPI : public API
{
public:
virtual const char* func1() override { /* Windows code */ }
virtual void func2() override { /* Windows code */ }
};
class LinuxAPI : public API
{
public:
virtual const char* func1() override { /* Linux code */ }
virtual void func2() override { /* Linux code */ }
};
API& API::instance() {
#if PLATFORM == WIN32
static WindowsAPI instance;
#elif PLATFORM = LINUX
static LinuxAPI instance;
#endif
return instance;
}
この例では、単純なコンパイラスイッチは、 API
クラスを適切なサブクラスにバインドしAPI
。このようにして、プラットフォーム固有のコードに結合することなくAPI
にアクセスできます。
スレッドセーフシントン
静的脱初期化安全なシングルトン。
あなたはシングルトンがそれを必要としなくなっシングルトンを使用するすべての静的オブジェクトまで破壊されないことを保証できるようにする必要があり、複数の静的オブジェクトとの時間があります。
この場合、 std::shared_ptr
は、プログラムの最後で静的デストラクタが呼び出されているときでも、すべてのユーザに対してシングルトンを生かし続けるために使用できます:
class Singleton
{
public:
Singleton(Singleton const&) = delete;
Singleton& operator=(Singleton const&) = delete;
static std::shared_ptr<Singleton> instance()
{
static std::shared_ptr<Singleton> s{new Singleton};
return s;
}
private:
Singleton() {}
};
注: この例はここのQ&Aセクションの答えとして表示されます。