0

メタプログラミング構造を使用しているため、シングルトンの実装が堅牢で一般的であると主張する人がたくさんいます。

私の目標は、派生クラスのコンストラクターをプライベートとして明示的に (手動で) 宣言する必要がないように、派生クラスにシングルトン ポリシーを適用することです。テンプレート化されたシングルトンを派生クラスのフレンドにすることで、インスタンスの静的変数とゲッターをポリシーとして単純に追加する方法があると思います。しかし、それはまったくエレガントではありません。

私はこのコードから始めました。これは、とりわけ、シングルトンの正しい (つまり完全な) 設計として与えられていますが、複数のインスタンスを明確に許可しています。

template <class CWrappedClass>
class CSingleton
{
protected:
    static CWrappedClass* ms_instance;
private:
    CSingleton(){}
    CSingleton(const CSingleton& ) {}
    CSingleton& operator = (const CSingleton&) {}

public:
    static CWrappedClass& GetInstance()
    {
        if (ms_instance == NULL)
            ms_instance = new CWrappedClass;
        return *ms_instance;
    }
};

template <class CWrappedClass>
CWrappedClass* CSingleton<CWrappedClass>::ms_instance = NULL;

そして、CRTP を使用した、この「ポリシー」のシングルトン クライアント:

class CThing : public CSingleton<CThing>
{
     // friend class CSingleton<CThing>; // only if ctor is private!
public:
    void DoNothing()
    {
        std::cout<<" Nothing \n";
    }
    CThing()
    {
        std::cout<<" single ";
    }
};

これは CRTP シングルトン ポリシーの正しい実装ではないことに注意してください。これは単なる問題の一部です。

コードはそのままではコンパイルされません。ベース シングルトン ポリシー クラスでは、そのコンストラクターがプライベートと宣言されているため、子がこのクラスのフレンドでない限り、派生インスタンスをサポートできません。通常、人々はコンストラクターを保護します。つまり、ユーザーが派生クラスを非シングルトン化することを妨げるものは何もありません。

問題/質問: 派生クラスのコンストラクターを手動で非公開にすることなく、シングルトン ポリシーを強制するメカニズムはありますか?

4

1 に答える 1

2

このパターンを使用したい場合:

  1. テンプレートのコンストラクターは、派生クラスがテンプレートにアクセスできるように、プライベートではなく保護する必要があります。そうしないと、独自のコンストラクターが基本クラスを構築できません。

  2. 派生クラスは、テンプレート(その基本クラス)をフレンドにし、プライベートコンストラクターを持つことができます。

または、コンパイルユニットの派生クラスからインスタンスを実際に構築するマクロを実装します。同様のモデルを使用したとき(強制的に、シングルトンを使用するコードを修正しましたが、実際のシングルトンが実装された方法でのみ変更しませんでした)、このオプションを選択しました。これは、実際にはboost::once.cppの構造を通過しました。ファイル。

于 2012-11-12T16:25:38.137 に答える