从重写函数调用重写函数
假设我在类 B 中有虚函数 foo(),并且我需要在 B 的派生类之一(类 D)中略有不同的行为。是否可以创建重写函数 D::foo() 并调用 B::foo( )从那里开始,经过特殊情况处理? 就像这样:
void D::foo()
{
if (/*something*/)
// do something
else
B::foo();
}
我不是在问这是否有效,我知道它会有效。 我想知道,就良好的 OOD 而言,这是否正确。
Suppose I have virtual function foo() in class B, and I need slightly different behavior in one of B's derived classes, class D. Is it OK to create an overriding function D::foo(), and call B::foo() from there, after the special case treatment? Like this:
void D::foo()
{
if (/*something*/)
// do something
else
B::foo();
}
I am not asking whether that would work, I know it will. I want to know, whether it is right in terms of a good OOD.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
这非常好。 事实上,执行某些操作的规范方法是调用基类方法,然后执行任何操作(或相反)。 我在这里想到
operator=
。 构造函数通常也以这种方式工作,即使这在初始化列表中有点隐蔽。This is perfectly good. In fact, the canonical way of performing some operations is calling the base class method, then do whatever (or the other way around). I am thinking of
operator=
here. Constructors usually work that way, too, even if this is a bit disguised in the initialization list.是的,只要不违反里氏替换原则,就完全可以。
Yes, its totally ok as long as you are not violating the Liskov Substitution Principle.
是的。
Yes, it is.
我见过 GUI 框架使用它来依赖基类的默认实现,其中包含用于发出错误信号/抛出异常/返回通用值的代码。
I have seen GUI frameworks use this to fall back on the base class's default implementation which contained code to signal errors/throw an exception/return a generic value.
没关系。 您给出的语法也可用于临时关闭多态性,即当您调用 obj->B::foo() 方法时,将从类 B 中选择方法,无论 foo() 是否为虚拟以及 obj 是否为实例B 与否(但它必须是扩展 B 的类的实例)。
It's ok. Syntax you had gave can be also used to temporary turn off polymorphism, i.e. when you call obj->B::foo() method will be chosen from class B regardless if foo() is virtual or not and if obj is instance of B or not (it must be an instance of class extending B though).
是的,这就是编译器每次生成构造函数和析构函数时为您所做的事情:例如调用母亲的构造函数和析构函数。 我经常在自己的代码中依赖这个“技巧”。
Yes it is , that's what your compiler do for you every time it generates a constructor and a destructor: calling the mother's one for instance. I often rely on that"trick" in my own code.
调用 base 的实现很好,但是有条件地执行它会使您脱离构造函数语义,这与其他答案中建议的相反。
您可能会通过两种方式遇到脆弱基类问题:
B::foo()
为整个层次结构提供通用行为(即,忘记该方法并不总是被调用)// do some
实际执行的操作!为了完整起见,让我们提一下对称设计方法:模板模式(调用特定子部分的基本实现)
It's fine to call base's implementation, but doing it conditionally moves you apart from constructor semantic, contrary to what have been suggested in other answers.
You may run into fragile base class issue in two ways :
B::foo()
provides common behavior for the whole hierarchy (ie, forgetting the method isn't always called)// do something
actually does !For completeness, let's mention a symmetric design approach : Template pattern (base implementation calling specific sub-part)