5

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

4

4 回答 4

14

那个网站是愚蠢的,并且教授糟糕的设计。

如果你抛出intor char*,那么你将不得不使用intor来捕捉它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但这里要注意的一点是:这不是必需的!

简而言之,您可以利用类层次结构。

于 2012-07-02T05:22:29.070 回答
2

如果您在代码中规定只抛出从 std::exception 派生的异常,那么捕获它们就更容易了。换句话说,您可以在 std::exception 上只使用一个 catch 子句:

catch (std::exception& e)
{
    log_message(e);
    throw;
}

但是如果你不遵循这条规则,那么你最终不得不在你不需要的时候编写 catch 子句。

于 2012-07-02T05:24:27.967 回答
1

主要是因为当你与其他人一起工作时,你必须就捕捉什么达成一致。如果我尝试 catch aconst std::exception&而你 throw const char*,那么我不会抓住你的东西,而且可能会发生坏事。

只要每个人都坚持下去,什么类型的被抛出和捕获并不重要。我想std::exception被选中是const char*因为它允许您将不仅仅是一个字符串放入异常对象中。它只是更灵活。

于 2012-07-02T05:22:22.003 回答
1

他其他答案的另一点是 -

如果你抛出一个 int 或一个字符串,并且你想捕获一个特定的错误,你就做不到。您必须捕获所有“int”异常,然后比较您想要捕获的异常,然后重新抛出您不准备处理的任何异常。如果您从异常继承,您可以捕获您想要处理的特定异常,并且仍然具有如果您想处理所有异常,您可以捕获 std::exception 的优势。

于 2012-07-02T07:22:12.843 回答