重写虚函数时的异常规范
考虑下面的代码:
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,则不会出现错误。
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 appear.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
扩展第 2 点:
A
的调用者期望只有int
出来,但如果您使用B
(其中,因为它是公开的)派生自A
,也意味着它可以用作A
),突然double
也可以出现,这会破坏A< /code> 的契约(只有
int
被抛出)。To expand on point 2:
A
's callers expect that onlyint
comes out, but if you use aB
(which, because it's publicly derived fromA
, also means it's usable as anA
), suddenlydouble
can come out too, and that would breakA
's contract (that onlyint
gets thrown).你的 B 违反了里氏替换原则 - 例如:
根据 A 的接口,这是有效的;特别是,我们不希望抛出双倍。但考虑一下我们是否要
使用您描述的接口进行调用,并且
were to throw a double.
Your B violates the Liskov Substitution Principle - eg:
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
with the interface you describe, and
were to throw a double.