重写虚函数时的异常规范

发布于 2024-08-23 13:48:58 字数 287 浏览 7 评论 0原文

考虑下面的代码:


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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

晚雾 2024-08-30 13:48:58
  1. 不要在 C++ 中使用异常规范。 与以下内容相比,这是非常违反直觉的: Java 的。
  2. 在派生类中具有更广泛的规范会破坏 LSP(里氏替换原则)。

扩展第 2 点:A 的调用者期望只有 int 出来,但如果您使用 B (其中,因为它是公开的)派生自 A,也意味着它可以用作 A),突然 double 也可以出现,这会破坏 A< /code> 的契约(只有 int 被抛出)。

  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).

你的他你的她 2024-08-30 13:48:58

你的 B 违反了里氏替换原则 - 例如:

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

根据 A 的接口,这是有效的;特别是,我们不希望抛出双倍。但考虑一下我们是否要

foo(new B)

使用您描述的接口进行调用,并且

B::f()

were to throw a double.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文