2016-01-04 22 views
8

私はテンプレートクラスの配列を持っている:C++ - のオーバーロード[]演算子

template <class T=int, int SIZE=10> 
class Array { 
    T TheArray[SIZE]; 
public: 
    void Initialize() { 
     for (int idx=0; idx < SIZE; idx++) { 
      TheArray[idx] = T(); 
     } 
    } 

    T& operator [](int idx) { 
     return TheArray[idx]; 
    } 

    T operator [](int idx) const { 
     return TheArray[idx]; 
    } 
} 

私は(私はネット上でこの例を見つけました)演算子オーバーロード[]上のいくつかの質問を持っています。

T& operator [](int idx)は、インデックスidxを持つ配列値への参照を返し、T operator [](int idx) constはその値を返します。 ただし、[]演算子を使用して参照または値が返されるかどうかはわかりません。

また、私がT operator [](int idx) const - >T operator [](int idx)に変更した場合、コンパイラは不平を言います。何故ですか? 戻り値の型が異なるだけなので、コンパイラが文句を言うのは理解できますが、constを追加したときになぜそれが文句を言わないのですか?これは、クラス内部のどれもが変更されていないことを意味します。

私はこの小さな主な実装をデバッグしようとした:

int main() { 
    int val; 
    Array<> intArray; 

    intArray.Initialize(); 
    val = intArray[1]; 
    printf("%d", intArray[1]); 
    intArray[1] = 5; 
} 

をその都度T& operator [](int idx)が呼び出されます。どうして?

ありがとうございます。

+0

「初期化」のような関数に対する適切なコンストラクタを優先します。 C++はオブジェクトの初期化に最適なツールを提供し、コンストラクタと呼ばれています。 – SergeyA

答えて

12

operator[]オーバーロードは、呼び出すオブジェクトのconst-修飾に基づいて選択されます。

Array<> intArray; 
intArray[1]; //calls T& operator[] 

const Array<> constArray; 
constArray[1]; //calls T operator[] 

あなたはT operator[]からconstを削除した場合、それらの間を選択する方法はありませんようメンバ関数は、同じconst -qualificationとパラメータを持つことができないので、エラーが発生します。

12

まずは、[]を文法砂糖としてthis->operator[]としてください。

thisが他の非constバージョンが呼び出されますconstポインタである場合、constバージョンが呼び出されます。

移動すると、const T& operator [](int idx) const {、つまりconstのバージョンがconstのリファレンスを返すようにする必要があります。それは深いコピーを取るオーバーヘッドを節約します。

最後に、const-機能の度合いは、その署名の一部であるです。これにより、const -nessに基づいてオーバーロードすることができます。さもなければ、operator[]の2つのバージョンを持つことができませんでした。

+1

私はconstの代わりに一時的なものを返すよう呼び出すこともありますが、ここでは矛盾、すなわち:[なぜ私はmemcpyでconst引数を使用できませんか?](http://stackoverflow.com/q/) 17669913/1942027)驚くべき挙動を防ぐために標準ライブラリに向けるべきであり、['std :: vector'](http://en.cppreference.com/w/cpp/container/vector/operator_at)はconst参照を返します。 –

関連する問題