2016-05-03 12 views
1

例外の形式を使用して範囲外の配列の値を返すのに問題があります。C++:例外処理で範囲外の配列から値を返す方法

Iクラスアレイを使用して例えば長さ10用と私のメインスクリプトで配列オブジェクトを作成します。配列の11番目の要素を特定の値に設定しようとしています。私のクラスの配列では、配列のインデックスが配列のサイズよりも大きい場合、この場合ArrayOutOfBoundsクラスから値を返す。私の主なスクリプトでは、ArrayOutofBoundsクラスからこのオブジェクトをキャッチして、範囲外のインデックスと、配列が範囲外であることを示すターミナルメッセージを出力しました。しかし、私は11番目の要素を設定しようとしていた実際の値をどのように返すのですか?

次のようになります。

クラスArrayOutOfBounds +演算子オーバーロード< <機能

class ArrayOutOfBounds { 
public: 

ArrayOutOfBounds(int index) : _index(index) {} ; 

int index() const { return _index ; } 

private: 
int _index ; 
} ; 

ostream& operator<<(ostream& os,const ArrayOutOfBounds& m) { 
    return (os << "Array index is out of bounds") ; 
} 

をクラスArray内の関数をバックスロー:

double& operator[](int index) { 
if(index > _size) { 
    ArrayOutOfBounds aoob(index) ; 
    throw aoob ;   
} 
return _arr[index] ; 

メインスクリプト:

int main() { 

Array array(10) ; 

try { 
    array[11] = 10 ; 
} 

catch(ArrayOutOfBounds aoob) { 
    cout << '\n' ; 
    cout << aoob << " (index, value): " << aoob.index() << ", " << 10 << endl ; 
} 

cout << '\n' ; 
return 0 ; 
} 

_arr [index]をスローする2番目のスロー値を追加しようとしましたが、2つのことをすぐにスローできないことを理解しました。

+3

コードをステップ実行して例外が発生していることを確認しましたか?そしてそれはインデックス> = _sizeでなければならないのですか? – thorsan

+0

OT:用語 - C++プログラムは*スクリプト*ではありません。 '_ 'で始まる変数名も標準によって予約されています。 – Galik

+1

['std :: exception'](http://en.cppreference.com/w/cpp/error/exception)から継承した場合、[' what'](http:// en。 cppreference.com/w/cpp/error/exception/what)メソ​​ッドを使用して、インデックスを含め、必要なものを書き出します。 – CoryKramer

答えて

2

参照に値を割り当てる前に例外がスローされるため、現在は書かれているため、operator[]では使用できません。

void setAt(int index, double value) { 
    if (index < 0 || index >= values.size()) 
     throw ArrayOutOfBounds{index, value}; 
    values[index] = value; 
} 

Live demo:代わりに次の2つのパラメータ、インデックスと値をとる値を設定する別のメンバ関数を書くことができoperator[]を使用しての

。そう、それはあなたがしようとすると、そのプロキシオブジェクトに値を代入した場合にのみ、その後、「範囲外」の状態であることができ、プロキシオブジェクトを返すこと

あなたでし変更operator[]は例外スローされます。

ArrayElementProxy operator[](int index) { 
    return ArrayElementProxy{*this, index};  
} 

class ArrayElementProxy { 
    Array* array_; 
    int index_; 
public: 
    ArrayElementProxy(Array& array, int index) : array_(&array), index_(index){} 
    Array& operator=(double value){ 
     array_->setAt(index_, value); 
     return *array_; 
    } 
    operator double() const{ 
     return array_->getAt(index_); 
    } 
}; 

Live demo.

しかし、私は(ちょうどvector<bool>を使用しようとしたことのある人に尋ねる)プロキシオブジェクトは、一般的に最もよく避けられると思います。

+0

あなたは親切にしています、ありがとう –

3

しかし、11番目の要素を設定しようとしていた実際の値を返すにはどうすればよいですか?

あなたは機能を使って何を設定されていません。この関数は参照を返すので、呼び出し元が何をしているのかはあなたのクラスには分かりません。値を設定してコピーを作成し、それを関数に渡して、それを知ることはできません。知っておく必要がある場合は、演算子を書き換えて関数演算子()をオーバーロードする必要があります。その後、インデックスとインデックスに設定する値を取り込むことができます。

あなたは、2つのパラメータに取るようにArrayOutOfBoundsを変更することができます。インデックスと値を入力し、catchブロック内でそれらにアクセスできます。

+0

ありがとう、私は確かにこのトラックに沿って考えていた –

関連する問題