假设我在B类中有虚函数foo(),我需要在B的派生类之一D类中略有不同的行为。是否可以创建重写函数D :: foo(),并调用B: :foo()从那里经过特殊情况处理?像这样:
void D::foo()
{
if (/*something*/)
// do something
else
B::foo();
}
我不是在问这是否会奏效,我知道会这样。我想知道,对于一个好的OOD来说它是否正确。
答案 0 :(得分:19)
这非常好。实际上,执行某些操作的规范方法是调用基类方法,然后执行任何操作(或者反过来)。我在这里想operator=
。构造函数通常也以这种方式工作,即使在初始化列表中有点伪装。
答案 1 :(得分:6)
是的,只要你没有违反Liskov替代原则,它就完全可以了。
答案 2 :(得分:4)
是的,是的。
答案 3 :(得分:1)
我已经看到GUI框架使用它来回退基类的默认实现,其中包含用于发出错误信号/抛出异常/返回通用值的代码。
答案 4 :(得分:1)
没关系。你给出的语法也可以用来临时关闭多态,即当你调用obj-> B :: foo()方法将从B类中选择,无论foo()是否为虚拟,如果obj是实例B与否(它必须是扩展B的类的实例)。
答案 5 :(得分:0)
是的,这就是你的编译器每次生成构造函数和析构函数时为你做的事情:例如调用母亲的一个。我经常依赖自己代码中的“技巧”。
答案 6 :(得分:0)
调用base的实现很好,但是有条件地会使你与构造函数语义分开,这与其他答案中的建议相反。
您可能会以两种方式遇到fragile base class问题:
B::foo()
为整个层次结构提供了共同的行为(即,忘记方法并不总是被调用)// do something
实际上做了什么!为了完整起见,我们提一下对称设计方法:Template pattern(基本实现调用特定的子部分)