7

考虑以下代码:


class A
{
public:
    virtual void f() throw ( int ) { }
};

class B: public A
{
public:
    void f() throw ( int, double ) { }
};

编译时,它说派生类 B 与 A 相比具有更宽松的抛出说明符。这有什么重要性?如果我们尝试交换它们的异常规范,使得 A::f() 抛出 int 和 double 而 B::f() 只抛出 int,则不会出现错误。

4

2 回答 2

14
  1. 不要在 C++ 中使用异常规范。与 Java 相比,这是非常违反直觉的。
  2. 在派生类中拥有更广泛的规范会破坏 LSP(Liskov 替换原则)。

扩展第 2 点:A的调用者期望它只会int出现,但是如果你使用 a B(因为它是公开派生自A,也意味着它可以用作 a A),突然double也可以出现,这会破坏A's contract (只会int被抛出)。

于 2010-03-05T15:08:47.117 回答
1

您的 B 违反了 Liskov 替换原则 - 例如:

void foo(A* a) throw() // 即我不会抛出
{
  尝试
  {
     a->f();
  }
  捕捉(整数)
  {}
}

根据 A 的接口这是有效的;特别是,我们预计不会抛出 double。但是考虑一下如果我们打电话给

富(新B)

使用您描述的界面,以及

B::f()
被扔双。

于 2010-03-05T15:16:43.073 回答