2013年11月25日月曜日

添字演算子のオーバーロードはconstと非const両方実装しよう

添字演算子 (subscript operator) をオーバーロードする時、constを付けないとconst呼び出しができなくなります。

非constで実装

class Foo {
    int arr[6];
public:
    Foo &operator [] (int i) {return arr[i];}
};
int main() {
    const Foo f_c;
    int v = f_c[0]; // ここでエラー
    Foo f;
    f[0] = 1;
}

逆に、constを付けると添字演算子を使用した要素の変更ができなくなってしまいます。

constで実装

class Foo {
    int arr[6];
public:
    const Foo &operator [] (int i) const {return arr[i];}
};
int main() {
    const Foo f_c;
    int v = f_c[0];
    Foo f;
    f[0] = 1; // 今度はここでエラー
}

こういう時にconstメンバ関数と非constメンバ関数のオーバーロードをします。

class Foo {
    int arr[6];
public:
    Foo &operator [] (int i) {return arr[i];} // 非constバージョン
    const Foo &operator [] (int i) const {return arr[i];} // constバージョン
};
int main() {
    const Foo f_c;
    int v = f_c[0]; // const関数が呼ばれる
    Foo f;
    f[0] = 1; // 非const関数が呼ばれる
}
このように両方実装することで、コンパイラが自動的にconstメンバ関数と非constメンバ関数のどちらか適切な方を呼び出してくれます。 (参考サイト: http://www.geocities.jp/ky_webid/cpp/language/020.html)

0 件のコメント:

コメントを投稿