根据这个站点,它完全可以用来抛出一个字符串或整数。我觉得这很干净,很容易理解。throw "description of what happened"
而不是的缺点是什么throw std::runtime_error("description of what happened")
?
4 回答
那个网站是愚蠢的,并且教授糟糕的设计。
如果你抛出int
or char*
,那么你将不得不使用int
or来捕捉它char*
。您可以使用const
.
如果你抛出std::runtime_error
,那么你可以使用它std::runtime_error const &
或者它的基类来捕捉它std::exception const &
。
那么它有什么好处呢?
这样做的好处是,如果您使用最终派生自的类抛出异常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
}
好处是您不需要编写三个 catch
块,因为f()
可能会抛出三种不同类型的异常。如果这对您有所帮助,您可以编写多个以不同方式处理它们。catch
但这里要注意的一点是:这不是必需的!
简而言之,您可以利用类层次结构。
如果您在代码中规定只抛出从 std::exception 派生的异常,那么捕获它们就更容易了。换句话说,您可以在 std::exception 上只使用一个 catch 子句:
catch (std::exception& e)
{
log_message(e);
throw;
}
但是如果你不遵循这条规则,那么你最终不得不在你不需要的时候编写 catch 子句。
主要是因为当你与其他人一起工作时,你必须就捕捉什么达成一致。如果我尝试 catch aconst std::exception&
而你 throw const char*
,那么我不会抓住你的东西,而且可能会发生坏事。
只要每个人都坚持下去,什么类型的被抛出和捕获并不重要。我想std::exception
被选中是const char*
因为它允许您将不仅仅是一个字符串放入异常对象中。它只是更灵活。
他其他答案的另一点是 -
如果你抛出一个 int 或一个字符串,并且你想捕获一个特定的错误,你就做不到。您必须捕获所有“int”异常,然后比较您想要捕获的异常,然后重新抛出您不准备处理的任何异常。如果您从异常继承,您可以捕获您想要处理的特定异常,并且仍然具有如果您想处理所有异常,您可以捕获 std::exception 的优势。