5

シンプルなカウンターです。このメソッドaddは、デフォルトでプライベート変数countを 1 ずつインクリメントするために呼び出されています。連鎖できるように関数からクラスを返しているのですが、出力を見てみると、 3回Counter呼び出したので3だと思っていたら1になってしまいました。add

#include <iostream>
#include <vector>

using std::cout;

class Counter {
    public:
        Counter() : count(0) {}

        Counter add() {
            ++count; return *this;
        }

        int getCount() {
            return count;
        }
    private:
        int count;
};

int main() {

    Counter counter;

    counter.add().add().add();

    cout << counter.getCount();

}
4

1 に答える 1

13

イディオムのチェーン化の全体的な考え方は、チェーン化された各呼び出しでの同じオブジェクトにアクセスすることに基づいています。これは通常、各変更メソッドから元のオブジェクトへの参照を返すことによって実現されます。これはあなたが宣言されるべきだった方法ですadd

    Counter &add() { // <- note the `&`
        ++count; return *this;
    }

そうaddすれば、連鎖式で を適用するたびに、の同じオブジェクトが変更されます。

元のコードでは、元のオブジェクトの一時コピーaddを から返します。そのため、(最初のアプリケーションの後) の各追加アプリケーションはadd、一時コピーで動作し、そのコピーを変更して、さらに別の一時コピーを生成します。これらの一時的なコピーはすべて、完全な式の最後に跡形もなく消えます。このため、add最初の呼び出し以外の呼び出しの効果を確認することはできません。

于 2012-08-17T19:05:44.597 に答える