26

假设我在 B 类中有虚函数 foo(),并且我需要在 B 的派生类 D 类中稍有不同的行为。创建覆盖函数 D::foo() 并调用 B::foo( ) 从那里,经过特殊情况处理?像这样:

void D::foo()
{
  if (/*something*/)
     // do something
  else
     B::foo();
}

我不是在问这是否可行,我知道它会。我想知道,就良好的 OOD 而言,它是否正确。

4

7 回答 7

22

这非常好。事实上,执行某些操作的规范方法是调用基类方法,然后执行任何操作(或相反)。我在想operator=这里。构造函数通常也以这种方式工作,即使这在初始化列表中有点伪装。

于 2009-05-13T10:09:17.780 回答
6

是的,只要您不违反 Liskov 替换原则,完全可以。

于 2009-05-13T10:08:25.613 回答
4

是的。

于 2009-05-13T10:07:21.373 回答
1

我已经看到 GUI 框架使用它来回退基类的默认实现,其中包含指示错误/抛出异常/返回通用值的代码。

于 2009-05-13T10:07:36.940 回答
1

没关系。您提供的语法也可用于临时关闭多态性,即当您调用 obj->B::foo() 时,将从类 B 中选择方法,无论 foo() 是否为虚拟且 obj 是否为 B 的实例与否(它必须是扩展 B 的类的实例)。

于 2009-05-13T10:19:21.820 回答
0

是的,这就是你的编译器每次生成构造函数和析构函数时为你做的事情:例如调用母亲的那个。我经常在自己的代码中依赖那个“技巧”。

于 2009-05-13T10:10:40.883 回答
0

调用 base 的实现很好,但是有条件地这样做会使您远离构造函数语义,这与其他答案中的建议相反。

您可能会以两种方式遇到脆弱的基类问题:

  • 通过假设B::foo()为整个层次结构提供共同的行为(即,忘记方法并不总是被调用)
  • 讨厌的问题取决于// do something实际做什么!

为了完整起见,让我们提一下对称设计方法:模板模式(调用特定子部分的基本实现)

于 2013-12-17T19:53:49.323 回答