2017-01-19 13 views
0

は、私は現在、次の形式の多項式を表すべきであるC++でPolynomial級を、書いている:a_0, ..., a_iはすべてint年代である読み取り専用[]演算子が使用されないのはなぜですか?

p(x) = a_0 + a_1*x^1 + a_2*x^2 + ... + a_i*x^i 

クラスは内部的に定数a_0, ..., a_iを格納するために、std::vector<int>タイプのメンバ変数a_を使用します。

i > degree of polynomial = a_.size() - 1 
:で a_i要因の1つを変更しようとしたときにこれは失敗します

int &operator[](int i) 
{ 
    return a_.at(i); 
} 

読み取りおよび書き込み:一定の要因にアクセスするにはoperator[]は、次のようにオーバーロードされています

読み取り専用:

int operator[](int i) const 
{ 
    if (i > this->degree()) { 
    return 0; 
    } 

    return a_.at(i); 
} 

わずかに異なる実装では、2つの異なるサイズの多項式の係数を快適にループすることができます(の多項式の次数を気にする必要はありません)。失敗 -

は、悲しいことに、私はoperator+ -overloading(operator[]この快適を利用し読み取り専用)するので、ここで何かを見逃しているようです。を-overloading

operator+

Polynomial operator*(const Polynomial &other) { 
    Polynomial res(this->degree() + other.degree()); 

    for (int i = 0; i <= res.degree(); ++i) { 
    for (int k = 0; k <= i; ++k) { 
     res[i] += (*this)[k] * other[i-k]; 
    } 
    } 

    return res; 
} 

は関与数学を気にしないでください。重要な点は、iは常に

0 <= i < res.a_.size() 

の範囲内でこれres[i]に書き込みをしていること、である有効です。しかし、(*this)[k]other[i-k]は、必ずしも範囲[0, (*this).a_.size() - 1]にあるとは限りませんインデックスからの読み取りを試みてください。

読み取り専用- operator[]の実装が正しくなるはずですか?私はまだ無効なインデックスでa_にアクセスしようとするとエラーが発生します。

res[i] += (*this)[k] * other[i-k]; 

平等の右側にある。特に一部:何がコンパイラはラインで読み書き -Implementationを使用する可能性があります。

私はエラーが書き込み読み出しおよび-の「間違った」の使用によって引き起こされる確信している - operator[]を。

if (k <= this->degree() && i-k <= other.degree()) { 
    res[i] += (*this)[k] * other[i-k]; 
} 

私はoperator[] -overloadingを使用して何をしないのです:追加のチェックが無効なアクセスを固定しているため? 読み取り専用 - operator[]がここで使用されていないのはなぜですか?

+1

バイナリの 'operator *'は通常 'const'です。 – molbdnilo

+1

'[]'に別のことをするのは、直感的で分かりにくく、混乱します。プログラマは同じ動作を期待しています。 – PaulMcKenzie

+0

'this'への特権アクセスを必要としないので、非メンバ'多項式演算子*(多項式const&lhs、多項式const&rhs) 'を好む。そして、そうです、時にはあなたが望むことをする魔法の '[]'よりも '' at ''が良いでしょう... – Useless

答えて

6

(*this)[k]は、非constを使用していますthisを含む関数はconstではありません。

したがって、非constオーバーロード[]がコンパイラによって推奨されます。

これは醜いconst_castを使用してラウンドすることができますが、実際には、[]オペレータの2つのバージョンの動作を可能な限り同じに保つ必要があります。また、のオーバーロードでは、である必要がありますが、インデックスの境界がチェックされているとは限りません。あなたのコードはこれと乖離しているので、コードの読者を混乱させる可能性があります。

+0

本当にありがとうございます。実際、 'operator *'オーバーロードは 'const'なので、' const_cast'は必要ありません。私はできるだけ早く答えを受け入れます。 – Herickson

関連する問題