【问题标题】:Calling overridden function from the overriding function从覆盖函数调用覆盖函数
【发布时间】:2010-10-25 19:41:24
【问题描述】:

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

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

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

【问题讨论】:

    标签: c++ inheritance oop virtual overriding


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        是的。

        【讨论】:

        • 普通、标准、正常、典型、广泛使用。确实,能够做到这一点是绝对必要的。
        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

          【讨论】:

          • 你不能保证函数不是从 B 的子类中调用的,在这种情况下你根本没有打开任何东西。
          • @xtofl:你说如果我有B扩展A,C扩展B,即AB::foo()允许调用 A::foo() ?
          • @xtolf:我刚刚验证了我的答案,它似乎是正确的。
          【解决方案6】:

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

          【讨论】:

            【解决方案7】:

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

            您可能会通过两种方式遇到fragile base class 问题:

            • 假设B::foo() 为整个层次结构提供通用行为(即,忘记方法并不总是被调用)
            • 严重的问题取决于 // do something 的实际操作!

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2012-08-09
              • 2021-04-17
              • 1970-01-01
              • 1970-01-01
              • 2010-10-30
              • 2015-03-12
              • 2011-05-31
              相关资源
              最近更新 更多