1

私の基本クラスは保護されたc'torを持つSingletonです。今、私はそれから別のクラスを派生させることができますが、派生クラスの関数内でその Base クラスのインスタンスを作成することはできません。これは、私の設計による予想される動作です。しかし、C++ 標準で正しいのか、それともコンパイラ固有の動作だけなのかを知りたいです。(将来このコードを移植したい場合に問題に直面しないようにするため)

class Singleton
{
protected:
    Singleton() {}

public:
    Singleton * GetInstance()
    {
        static Singleton* InstanceCreated = NULL ;

        if (!InstanceCreated)
            InstanceCreated = new Singleton ;

        return InstanceCreated ;
    }
};

class Deringlton : public Singleton
{
public:
    Deringlton()
    {
        Singleton * pSing ;
        // pSing = new Singlton ; // Cannot create object of singlton 
                                  // (Despite class is derived from singlton)
    }
};
4

5 に答える 5

4

一般的なシングルトン実装を提供するより良い方法は、 CRTPを使用し、そのテンプレートから直接継承することだと思います。これは、すべてのクラスが CRTP ベースからのみ継承するシングルトン パターンを自動的に実装することを意味します。

template<typename DERIVED>
class generic_singleton
{
private:
    static DERIVED* _instance;

    static void _singleton_deleter() { delete _instance; } //Function that manages the destruction of the instance at the end of the execution.

protected:
    generic_singleton() {}
    virtual ~generic_singleton() {} //IMPORTANT: virtual destructor

public:
    DERIVED& instance() //Never return pointers!!! Be aware of "delete Foo.instance()"
    {
        if(!_instance)
        {
            _instance = new DERIVED;
            std::atexit( _singleton_deleter ); //Destruction of instance registered at runtime exit (No leak).
        }
        return static_cast<DERIVED&>( _instance );
    }
};

template<typename DERIVED>
DERIVED* generic_singleton<DERIVED>::_instance = nullptr;

メモリ解放は、アプリケーションの最後に削除を行う関数を に登録することで提供されますstd::ateexit()

于 2013-08-16T12:14:34.990 に答える
1

単なる静的変数ではなくポインターを持つことのポイントは何ですか?

class Singleton
{
public:
    static Singleton& instance()
    { static Singleton z; return z; }
private:
    Singleton() {}
    ~SIngleton() {}
};

それを導き出す価値はありません。

このパターンをテンプレートとしてコーディングしたい場合は、次のことができます

template<class S>
S& instance_of() { static S z; return z; }

そして、私的なctor / dtorを持つinstance_of<yourclass>()、の友達を作ります。yourclass

静的変数を使用すると、オブジェクトが適切に構築および破棄されることが許可されます。(残りのリークされたポインタとは異なり、デストラクタ呼び出しはありません...)

于 2013-08-16T12:33:52.607 に答える