22

operator[] の get と set の違いがわかりません。これらの関数呼び出しの違いを説明する必要があります。

cout << data[5];
data[5] = 1;

私はそれをグーグルで検索しましたが、見つけた答えはまだ役に立ちませんでした。人々は、const を追加することによって、メソッドの署名を異なるものにすることを提案しました。私はそれをしましたが、両方とも同じメソッドを呼び出しました。

私が使用した署名があります:

const T& operator[](unsigned int index) const;
T& operator[](unsigned int index);

私は何を間違っていますか?

4

4 に答える 4

26

解決策は、実際の操作を遅らせる「プロキシ」オブジェクトを使用することです。

#include <vector>
#include <iostream>

template<typename T>
struct MyArray {
    std::vector<T> data;
    MyArray(int size) : data(size) {}

    struct Deref {
        MyArray& a;
        int index;
        Deref(MyArray& a, int index) : a(a), index(index) {}

        operator T() {
            std::cout << "reading\n"; return a.data[index];
        }

        T& operator=(const T& other) {
            std::cout << "writing\n"; return a.data[index] = other;
        }
   };

   Deref operator[](int index) {
       return Deref(*this, index);
   }
};

int main(int argc, const char *argv[]) {
    MyArray<int> foo(3);
    foo[1] = 42;
    std::cout << "Value is " << foo[1] << "\n";
    return 0;
}

非 const インスタンスから読み取る必要がある可能性があるため、単純const性は使用できません。これが、操作を遅らせる必要がある理由です。割り当てはアクセスの「後」に行われ、アクセスがアクセスされたかどうかコンパイラーは通知しません。後で割り当てのターゲットとして使用されるかどうか。

したがって、アクセス時に、要求されたインデックスを保存し、読み取りまたは書き込み操作が行われているかどうかを確認するのを待つという考え方です。プロキシから暗黙的な変換演算子を提供することTで、読み取り操作がいつ発生するかを知ることができます。代入演算子をプロキシに提供することでT、書き込みがいつ発生するかを知ることができます。

于 2013-10-07T05:53:47.607 に答える
1

添字の通常の意味と互換性を持たせるために、添字演算子は通常、フェッチされた要素への参照を返します。参照を返すことにより、代入の両側で添え字を使用できます。

したがって、通常は、この演算子の const バージョンと非 const バージョンの両方を定義することもお勧めします。オブジェクトに適用された場合、subscript は const への参照を返して、返されたオブジェクトに割り当てられるようにする必要があります。

----C++ 入門書、第 5 版

于 2013-10-07T05:57:53.090 に答える
0

constのバージョンがデータ オブジェクトに対してoperator[]呼び出されます。const

const Data data;
cout << data[5];
于 2013-10-07T05:48:54.883 に答える