このサイトによると、文字列または整数をスローするのに完全に使用できます。これはかなりきれいで理解しやすいと思います。throw "description of what happened"
ではなく、の欠点は何throw std::runtime_error("description of what happened")
ですか?
4 に答える
そのサイトは愚かで、悪いデザインを教えています。
int
またはを投げる場合は、またはのみchar*
を使用してキャッチする必要があります。で修飾できます。int
char*
const
をスローすると、 またはその基本クラスstd::runtime_error
を使用してキャッチできます。std::runtime_error const &
std::exception const &
では、何が良いのでしょうか?
それについての良い点は、最終的に から派生したクラスを使用して例外をスローする場合、例外をスローするために使用される派生クラスに関係なく、例外を として受け入れるブロックを1 つstd::exception
だけ作成できることです。catch
std::exception const&
以下に一例を示します。
void f(A & a)
{
if ( !check_arg(a) )
{
throw std::invalid_argument("invalid argument");
}
else if ( !check_size(a) )
{
throw std::length_error("invalid length");
}
//code
if(someCondition)
{
//assume your_own_defined_exception's ultimate base is std::exception
throw your_own_defined_exception("condition unsatisfied");
}
//...
}
今興味深い部分:
try
{
f(a); //it can throw exception of at least 3 types!
}
catch(std::exception const &e) //all types can be caught by just one catch!
{
//handle this case
}
良い点は、3 つの異なるタイプの例外をスローする可能性があるという理由だけで、 3 つのブロックを記述する必要がないことです。それが何らかの方法であなたに利益をもたらすのであれば、それらを異なる方法で処理するために複数書くことができます。ただし、ここで注意すべき点は、必須ではないということです。 catch
f()
catch
つまり、クラス階層を利用できます。
std::exception からのみ派生した例外をスローするようにコードでルールを作成すると、それらをキャッチするのが簡単になります。つまり、std::exception に catch 句を 1 つだけ指定できます。
catch (std::exception& e)
{
log_message(e);
throw;
}
しかし、このルールに従わないと、必要のないときに catch 節を書かなければならなくなります。
彼の他の回答からの1つの追加ポイントはこれです-
int または文字列をスローし、特定のエラーをキャッチしたい場合はできません。すべての「int」例外をキャッチしてから、キャッチしたいものを比較してから、対処する準備ができていないものを再スローする必要があります。例外から継承すると、処理したい特定の例外をキャッチできますが、それらすべてを処理したい場合は std::exception をキャッチするだけでよいという利点があります。
主な理由は、他の人と作業するときは、何をキャッチするかについて合意する必要があるからです。私が a をキャッチしようとしてconst std::exception&
、あなたが を投げるconst char*
と、あなたのものをキャッチできず、悪いことが起こる可能性があります。
誰もがそれに固執する限り、どのタイプが投げられてキャッチされるかは問題ではありません. 例外オブジェクトに文字列以上のものを入れることができるため、std::exception
選択されたと思います。const char*
より柔軟です。