根据this site,抛出一个字符串或整数是完全可用的。我觉得这很干净,很容易理解。 throw "description of what happened"
而不是throw std::runtime_error("description of what happened")
的缺点是什么?
答案 0 :(得分:14)
该网站很愚蠢,教导设计不好。
如果您抛出int
或char*
,则必须使用int
或char*
来抓住它。您可以使用const
符合条件。
如果您抛出std::runtime_error
,则可以使用std::runtime_error const &
或其基类std::exception const &
来捕获它。
那有什么好处呢?
关于它的好处是如果你使用最终派生自std::exception
的类抛出异常,那么你只能编写一个catch
块,它接受异常为std::exception const&
,不管which derived class是否用于抛出异常。
以下是一个例子:
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
以便以不同方式处理它们,如果这对您有所帮助。但需要注意的是:不是一项要求!
简而言之,您可以利用类层次结构。
答案 1 :(得分:2)
如果您在代码中使用规则来抛出仅从std :: exception派生的异常,那么捕获它们会更容易。换句话说,你可以在std :: exception上有一个catch子句:
catch (std::exception& e)
{
log_message(e);
throw;
}
但是如果你不遵循这条规则那么你最终不得不在不需要时编写catch子句。
答案 2 :(得分:1)
主要是因为当你与其他人一起工作时,你必须同意接受什么。如果我尝试抓住const std::exception&
并抛出const char*
,那么我就不会抓住你的东西,可能会发生不好的事情。
只要每个人都坚持下去,抛出和抓住什么类型并不重要。我猜std::exception
被选为const char*
,因为它允许您将不仅仅是一个字符串放入异常对象中。它更灵活。
答案 3 :(得分:1)
他的其他答案还有一点是 -
如果你抛出一个int或一个字符串而你想要捕获一个特定的错误,你就不能。 你必须捕获所有“int”异常,然后比较你想要捕获的异常,然后重新抛出任何你不准备处理的异常。如果从异常继承,你可以捕获你想要处理的特定异常,并且如果你想要处理它们,你仍然可以捕获std :: exception。