1

ジェネリック リンク リスト クラスを作成しており、逆方向反復子クラスで * 演算子をオーバーロードしています。ここに私が持っているものがあります:

try
{
    return this->item->data;
}
catch (...)
{
    cout << "OUT OF RANGEEEEE" << endl;
}   

itemリンク リスト クラスのノードである は、ポインターが rend() の位置を指しているため、nullptr である可能性があります。その場合、プログラムを引き続き実行できるように、その例外をどのように処理できますか? このコードで実行しようとしましたが、プログラムがクラッシュします。

また、代わりにこのようなことをしてもいいですか?

if (item == nullptr)
{
    throw std::out_of_range("Error message here!");
}
else
{
    return this->item->data;
}

編集:だから、2番目の実装の方が優れていると思いますか? それでも、2 番目の実装でプログラムを実行すると、プログラムを続行できません。どうすればより安全になり、プログラムが引き続き実行されるようになりますか?

4

2 に答える 2

3

catch ブロック1に入ると、プログラムはまだ実行されています。続行するには、 以外のものを返す必要がありますthis->item->data。あなたが返すものは、あなたを呼び出している関数にとって何が意味があるかによって異なります。

私見、これは例外の悪いユースケースです。リンクされたリストの最後に到達することは例外ではありません。それは正常であり、予期されていることです。おそらく、例外をスローしたいのでreturn this->item->data、リストの最後に到達したときに特別なケースを行う必要はありません。ただし、続行するには、何かを返す必要があり、呼び出し元はそれを確認する必要があります。その作業を別の場所に移動し、その過程で例外のコストを支払うだけです。より良い解決策は、null が最も意味のある場所でチェックして実行することです。例外なく、追加料金なし。


  1. catch (...)この場合には広すぎます。それはすべてをキャッチします。std::out_of_rangeあなたは本当にそれをまたはその祖先の1つに制限しようとするべきです. そうしないと、予期しないものが catch ブロックにまとめられてしまい、それらを処理する準備ができていない可能性があります。
于 2012-12-10T17:26:32.107 に答える
2

null ポインターの逆参照は未定義の動作です。例外をスローするように (標準で) 指定されたことはありません。それが、最初の例がクラッシュする理由です。

それがあなたが望む動作であれば、2番目の例は良いです。標準ライブラリの動作は、無効な逆参照をそのまま (未定義) のままにすることです。しかし、より安全な代替手段を実装したい場合は、自由に実装できます。

どうすればより安全になり、プログラムが引き続き実行されるようになりますか?

どのレベルでも try-catch ブロックを使用できます。例えば:

try {
    MyListType<int> my_list;
    // do a bunch of stuff here involving my_list::iterators
    // If one is improperly dereferenced, an `std::out_of_range`
    // exception will be thrown, and caught below
} catch (std::out_of_range & e) {
    // your error handling
}

ただし、おそらくから派生して、独自の特定のタイプの例外を作成することをお勧めしますstd::out_of_range。そうすれば、処理する準備ができていない可能性のある他のライブラリからの例外をキャッチすることはありません。

于 2012-12-10T17:24:06.740 に答える