web-dev-qa-db-ja.com

定数および非定数演算子のオーバーロード

私はいくつかの詳細な説明が必要であるという混乱したトピックを持っています。 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]でのみ呼び出されるという私の仮説。

助けてくれてありがとう。

23
James Wilks

両方のバージョンが使用可能な場合、ロジックは非常に簡単です。constバージョンはconstオブジェクトに対して呼び出され、nonconstバージョンはconstオブジェクトに対して呼び出されます。それで全部です。

コードサンプルでは、​​aは非constオブジェクトです。つまり、すべての場合に非constバージョンが呼び出されます。 constバージョンは、サンプルでneverと呼ばれます。

2つのバージョンを持つことのポイントは、非constオブジェクトには「読み取り/書き込み」アクセスを実装し、constオブジェクトには「読み取り」アクセスのみを実装することです。 constオブジェクトの場合constバージョンのoperator []が呼び出され、const double &参照を返します。 const参照を介してデータを読み取ることはできますが、書き込むことはできません。

27
AnT

上記の答えを補完するコード例を提供するには:

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
0
echo