2

以下はシングルトンクラスのコードです


class single{
private:
    int i;
    single(int x): i(x){ 

    }
public:
    static single& getInstance(){
        static single s(10);
        return s;
    }

    void incPrint(){
        ++i;
        cout i  " ";
    }
};

これで、同じコードで2つの異なるコードに対して2つの異なる結果が得られます


single d1 = single::getInstance();
    d1.incPrint();
    d1.incPrint();

    single d2 = single::getInstance();
    d2.incPrint();
    d2.incPrint();

このコードは次の出力を生成します。

11 12 11 12

一方、このコードは


    single & d1 = single::getInstance();
    d1.incPrint();
    d1.incPrint();

    single & d2 = single::getInstance();
    d2.incPrint();
    d2.incPrint();

結果を生成します

11 12 13 14

ここで、後者は目的の出力です。これは、設計上の問題またはユーザーコーディングの問題によるものですか?2番目の結果のみが得られるようにするにはどうすればよいですか?

ありがとう

4

3 に答える 3

10

T x = foo()コピーを作成します。

または、コピーを作成したかのように動作します。

一方、参照を返すT& x = foo()場合は、参照のみを作成します。fooT&


コピーコンストラクターとコピー代入演算子をプライベートにします。それは人々がすべてのコピーを作成することを防ぎます。コピー代入演算子をプライベートにすると、自己コピーができなくなります。

からシングルトンへのポインタを返すことは代替手段ではありませんgetInstance。これは、インスタンスが常に存在するという保証に人々が気付かないようにする確実な方法です。ポインターは、それがnullpointerである可能性があることを示します。

ただし、最善の代替策は、回避できる場合はシングルトンを使用しないことです。シングルトンには多くの問題があります。これらの問題には、ライフタイム管理、スレッドセーフ、およびメモリリークを検出するツールとの相互作用が含まれます。

于 2011-11-02T02:15:18.963 に答える
2

コピーコンストラクターを削除します(プライベートにします)。それは人々がコピーを作るのを防ぐでしょう。

もう1つの方法は、getInstance()のシングルトンへのポインターを返すことです。それは、シングルトンへの参照があることを人々に知らせる確実な方法です。

3番目の選択肢は、共有データの周りにコピー可能なラッパークラスを用意することです。このラッパーには、シングルトンへのポインターなどがあり、コピー可能です。

于 2011-11-02T02:07:15.797 に答える
2

シングルトン変数への参照を適切に返していますが、それを割り当てているのが問題です。

このコード:

single d1 = single::getInstance();

意味:

タイプの新しい変数を作成しsingle、返された参照をコピーして初期化します。したがって、これを行うたびに、シングルトン変数を使用する代わりに、新しい変数を作成します。

このコード:

single & d1 = single::getInstance();

意味:

返された参照と同じ変数への新しい参照を作成します。したがって、これを行うたびに、必要に応じてシングルトン変数への参照を取得します。

自分自身(および他の人)がこの間違いを犯さないようにするには、コンストラクターをプライベートにする必要があります。

于 2011-11-02T02:11:02.467 に答える