覆盖虚函数时的异常规范

时间:2010-03-05 15:05:18

标签: c++ exception virtual-functions exception-specification

请考虑以下代码:


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,则不会出现错误。

2 个答案:

答案 0 :(得分:13)

  1. Don't use exception specifications in C++.与Java相比,这是非常反直觉的。
  2. 在派生类中具有更宽的规范会破坏LSP(Liskov替换原则)。
  3. 要扩展第2点:A的来电者希望只有int出来,但如果您使用B(因为它是公开派生自A },也意味着它可用作A),突然double也会出现,这会破坏A的合约(只会int被抛出)。

答案 1 :(得分:1)

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

void foo(A* a) throw() // ie I will not throw
{
  try
  {
     a->f();
  }
  catch(int)
  {}
}

根据A的界面有效;特别是,我们不希望抛出双倍。但请考虑我们是否打电话

foo(new B)

使用您描述的界面,并且

B::f()
会抛出一个双倍。