1. ホーム
  2. c++

[解決済み】C++ シングルトンデザインパターン

2022-03-23 06:08:26

質問

最近、C++のSingletonデザインパターンの実現・実装にぶつかった。それは次のようなものでした(実例から採用しました)。

// a lot of methods are omitted here
class Singleton
{
   public:
       static Singleton* getInstance( );
       ~Singleton( );
   private:
       Singleton( );
       static Singleton* instance;
};

この宣言から、インスタンス・フィールドはヒープ上で開始されることが推測できます。つまり、メモリの割り当てが行われているのです。私にとって全く不明なのは、そのメモリが正確にいつ割り当て解除されるのか?それともバグやメモリリークがあるのでしょうか?実装に問題があるように思えます。

私の一番の疑問は、どうすれば正しい方法で実装できるのか、ということです。

どのように解決するのですか?

2008年に私は、遅延評価、破壊保証、技術的にはスレッドセーフではない、SingletonデザインパターンのC++98実装を提供しました。

どなたかc++でSingletonのサンプルを提供していただけませんか?

ここでは、遅延評価、正確な破棄、そして、SingletonデザインパターンのC++11実装を更新しています。 スレッドセーフ .

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
        // ========
        // Don't forget to declare these two. You want to make sure they
        // are inaccessible(especially from outside), 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++プログラマーが知っておくべき一般的な未定義の動作とは?

ドブス先生 C++とダブルチェック・ロックの危険性。パート1