C ++异常:为什么使用或扩展std :: exception?

时间:2012-07-02 05:17:10

标签: c++ exception

根据this site,抛出一个字符串或整数是完全可用的。我觉得这很干净,很容易理解。 throw "description of what happened"而不是throw std::runtime_error("description of what happened")的缺点是什么?

4 个答案:

答案 0 :(得分:14)

该网站很愚蠢,教导设计不好。

如果您抛出intchar*,则必须使用intchar*来抓住它。您可以使用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。