1. ホーム
  2. c++

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

2022-03-05 05:05:15

質問

最近、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