开发者

Exception specification when overriding a virtual function

Consider the following code:


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

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

When compiled, it says that derived class B has a looser throw specifier compared to A. What is the importance of this? If we try to exchange their exception specification, such that A::f() throws int and double while B::f() throws only int, the error does not ap开发者_运维技巧pear.


  1. Don't use exception specifications in C++. It's very counter-intuitive compared to, say, Java's ones.
  2. Having a wider specification in the derived class breaks LSP (Liskov Substitution Principle).

To expand on point 2: A's callers expect that only int comes out, but if you use a B (which, because it's publicly derived from A, also means it's usable as an A), suddenly double can come out too, and that would break A's contract (that only int gets thrown).


Your B violates the Liskov Substitution Principle - eg:

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

This is valid according to the interface for A; in particular, we do not expect a double to be thrown. But consider if we were to call

foo(new B)

with the interface you describe, and

B::f()
were to throw a double.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜