0

私がシングルトンクラスを持っていると仮定しましょう:

class Singleton {
public:
    static Singleton* getInstance();
    void doit();
    std::vector<Object*>& getVector();

private:
    std::vector<Object*> _vector;
    static Singleton *instance;
    Singleton();
    ~Singleton();
    Singleton(const Singleton&);
};

class Delegator {
public:
        void main();
}
  • このdoitメソッドでは、_vectorオブジェクトへのポインタをに入力します。
  • main()クラスから、結果Delegatorを呼び出しgetVector()て表示します。

この抽象化を考えると、次の質問があります。

  1. main()fromのオブジェクトのインスタンスへのすべてのポインタを削除できますかDelegator(結果を表示した後)。はいの場合、これは推奨されますか?
  2. シングルトンが破壊されることはありますか?言い換えれば、返される参照はgetVector()常に有効ですか?
  3. のベクトルのコピーではなく、ベクトルへの参照を返しますgetVector()。ベクトルにはオブジェクトへのポインタのみが含まれ、クラス外のベクトルコンテンツは変更されないことを考えるとSingleton、参照を返すことで得られる効率はありますか?

前もって感謝します

4

3 に答える 3

4

通常、シングルトンパターンは次のようになります(インスタンスのポインターの代わりに参照を使用するなど、他のバリエーションも可能です)。

singleton.h:

class Singleton {
public:
    static Singleton* getInstance();
    ...

private:
    static Singleton *instance;
    Singleton();                 //permit construction of instances
    ~Singleton();                //permit deletion of instances
    Singleton(const Singleton&); //don't provide an implementation for copy-ctr.
};

singleton.cpp:

Singleton *Singleton::instance = 0;

Singleton::Singleton() {
    // init your stuff
}

Singleton::~Singleton() {
}

Singleton *Singleton::getInstance() {
    if(!instance) instance = new Singleton();
    return instance;
}

あなたの場合、シングルトンパターンに違反するシングルトンインスタンスのコピーを返します。

2.質問に答えるには:シングルトンは決して削除しないでください。ただし、デストラクタを定義してプライベートにすることができます。そうしないと、呼び出し元ができますdelete Singleton::getInstance()。これはお勧めできません。

そうは言っても、シングルトンはほとんどの場合アンチパターンと見なされます。ほとんどの場合、ユーティリティクラスの方が適しています。ユーティリティクラスは非常によく似た概念ですが、インスタンスを使用する代わりにすべてを静的に実装します。初期化コードが必要な場合は、init()メソッドを使用してこれを行います(コンストラクターが関与していないため)。

于 2013-01-02T14:38:54.760 に答える
2

あなたが尋ねなかった質問に対する私の最初の答えはこれです:

シングルトンは使用しないでください。これはアンチパターンです。それはそれが触れるコードを悪化させます。それはテスト容易性を殺し、将来あなたのプログラムを修正することをより難しくします。

この非常に優れた記事では、シングルトンが悪いアイデアである理由について詳しく説明しています。

あなたが尋ねた質問に答えるために...

  1. はい、できます。もちろん、これらのポインターは引き続きベクター内にあるため、ベクターには大量のダングリングポインターが含まれます。したがって、ベクトルもクリアする必要があります。
  2. あなたが持っているコードでそれは決して破壊されません。シングルトンをメモリリークにするいくつかの定義による。そうです、参照は常に有効です。
  3. はい、参照を返すことでパフォーマンスが大幅に向上します。ベクトルをコピーするということは、ベクトル内のすべての要素のコピーを作成することを意味します。これは、ポインタが指すものではなく、すべてのポインタがコピーされることを意味することに注意してくださいObject。さらに、コピーを返し、main関数にすべてのポインターを削除させると、大量のダングリングポインターが含まれるベクトルが存在することが絶対に保証されます。
于 2013-01-02T15:09:48.543 に答える
2
  1. それは完全にあなたの要件とデザインに依存します。提示されたコードは、この観点からは中立です。

  2. 繰り返しますが、それはあなたの設計と実装次第です。それsingleton pattern自体は生涯を意味するものではありません。singletonが特定の存続期間にわたって有効である必要がある場合は、他の方法でそれを確認する必要があります(たとえば、そのグローバルインスタンスを定義します)。

  3. はい、パフォーマンスが向上します。のインスタンスはvector単純ではなくarray、実際に保存されている情報以外にかなりの量のデータが含まれています。値で返される場合、すべてのデータがコピーされます(この説明の最適化は別として)。また、別の回答で正しく指摘されているように、値で返すと実際にはが壊れますsingleton pattern

于 2013-01-02T14:49:16.900 に答える