C++中的松散抛出说明符错误

raj*_*jan 10 c++ exception

以下代码生成"Looser throw specifier error".你能帮我解决这个错误吗?

class base
{
    virtual void abc() throw (exp1);
}

void base::abc() throw (exp1)
{
    ......
}

class sub : public base
{
    void abc() throw(exp1, exp2);
}

void sub::abc() throw (exp1, exp2)
{
    .....
}
Run Code Online (Sandbox Code Playgroud)

Mik*_*our 13

问题出现了,因为子类必须可以在任何可以使用基类的地方使用,因此不能抛出除基类中指定的异常类型之外的任何异常类型.

有三种解决方案:

  1. 修改基类说明符以包括任何子类可能需要抛出的每个异常类型
  2. 修改每个子类以处理除基类中指定的异常类型之外的每个异常类型
  3. 删除异常说明符.

我建议删除它们; 他们被广泛认为是一个坏主意,部分是因为这样的问题.正如Matthieu所指出的那样,标准委员会同意,并且在下一版本的标准中,异常说明符将被弃用.

  • 事实上,它们在新标准中被弃用,支持`noexcept`:即使用`noexcept`来表示不能抛出任何异常(相当于`throw()`但是在违反的情况下没有运行时诊断合同)或根本不使用任何说明者,这相当于说该方法可以抛出任何东西. (5认同)

jrc*_*ada 6

当您在派生类中使用throw说明符覆盖虚方法时,派生类中的方法不能抛出比超类中的方法更多的异常.如果您被允许这样做,您可以通过覆盖子类中的方法来破坏超类的公共API创建的契约.

在你的例子中,你说base :: abc只能抛出exp1.但是,如果你有一个类型为base的指针,它实际上是指向一个sub的实例,那么突然abc除了exp1之外还可以抛出exp2.

要解决此问题,您需要从子类中的throw说明符中删除exp2,或者将exp2添加到超类的throw说明符中.