私はいくつかの詳細な説明が必要であるという混乱したトピックを持っています。 constバージョンと非constバージョンでオーバーロードする演算子です。
// non-const
double &operator[](int idx) {
if (idx < length && idx >= 0) {
return data[idx];
}
throw BoundsError();
}
クラスのこの関数部分がインデックスを取得し、その論理をチェックし、クラス内の配列データのインデックスを返すことを理解しています。同じ本体を持つ関数もありますが、関数呼び出しは
const double &operator[](int idx) const
なぜ2つのバージョンが必要なのですか?
このサンプルの質問も詳しく説明します。以下の各インスタンスでどのバージョンが使用されていますか?
Array a(3);
a[0] = 2.0;
a[1] = 3.3;
a[2] = a[0] + a[1];
Constバージョンはa[2]
またはa[0]
を変更するリスクがないため、a[1]
でのみ呼び出されるという私の仮説。
助けてくれてありがとう。
両方のバージョンが使用可能な場合、ロジックは非常に簡単です。const
バージョンはconst
オブジェクトに対して呼び出され、nonconst
バージョンはconst
オブジェクトに対して呼び出されます。それで全部です。
コードサンプルでは、a
は非const
オブジェクトです。つまり、すべての場合に非const
バージョンが呼び出されます。 const
バージョンは、サンプルでneverと呼ばれます。
2つのバージョンを持つことのポイントは、非const
オブジェクトには「読み取り/書き込み」アクセスを実装し、const
オブジェクトには「読み取り」アクセスのみを実装することです。 const
オブジェクトの場合const
バージョンのoperator []
が呼び出され、const double &
参照を返します。 const参照を介してデータを読み取ることはできますが、書き込むことはできません。
上記の答えを補完するコード例を提供するには:
Array a(3);
a[0] = 2.0; //non-const version called on non-const 'a' object
const Array b(3);
double var = b[1]; //const version called on const 'b' object
const Array c(3);
c[0] = 2.0; //compile error, cannot modify const object