请考虑以下代码:
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,则不会出现错误。
答案 0 :(得分:13)
要扩展第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()会抛出一个双倍。