views:

367

answers:

6

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.

+3  A: 

Yes, it is.

Daniel Daranas
Common, standard, normal, typical, widely-used. Indeed, it's absolutely essential to be able to do this.
S.Lott
+1  A: 

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.

dirkgently
+3  A: 

Yes, its totally ok as long as you are not violating the Liskov Substitution Principle.

Alex Jenter
+6  A: 

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.

Gorpik
A: 

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.

yves Baumes
A: 

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

You can't guarantee the function isn't called from a subclass of _B_, in which case you're not turning of anything at all.
xtofl
@xtofl: You say that if I have B extends A, C extends B, i.e. A<B<C class hierarchy, and C obj;, then calling obj->B::foo() is permitted to call A::foo() ?
@xtolf: I just verified my answer and it appears to be correct.