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

Ste*_* Lu 5 c++ exception

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

Naw*_*waz 14

该网站是愚蠢的,并教导糟糕的设计.

如果你扔int或者char*,那么你将不得不使用intchar*仅使用它.您可能符合条件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");                         
    }
    //...

}
Run Code Online (Sandbox Code Playgroud)

现在有趣的部分:

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
}
Run Code Online (Sandbox Code Playgroud)

好处是你不需要三个 catch块只是因为f()可能抛出三种不同类型的异常.如果以某种方式使您受益,您可以编写多个catch不同的方式来处理它们.但这里要指出的是:这不是一个要求!

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

  • @StevenLu如果你派生自己的异常类,那么你重新发明轮子,并可能破坏依赖于捕获std :: exception的代码.虽然这可能适用于您的个人项目,但这会使您的代码难以分发给其他人.标准方法是具有特定于应用程序的异常层次结构,该子层次结构是`std :: exception`的子类.例如,让所有异常都是`StevenLuException`的子类,它是`std :: exception`的子类. (3认同)