So you have to use "double dispatch" to achieve this. How crufty.
Basically, as the wikipedia link says,
The problem is that, while virtual functions are dispatched dynamically in C++, function overloading is done statically.
So, what you have to do is modify class Cat
:
struct Cat : public Animal
{
virtual void talkTo( Animal* o ) {
//puts( "Cat-Animal" ) ;
o->talkTo( this ) ; // TURN THE INVOKATION AROUND ("double dispatch")
}
virtual void talkTo( Cat* o ) {
puts( "Cat says meow to Cat" ) ;
}
} ;
Now, in
cat->talkTo( animalCatPtr ) ;
animalCatPtr
is actually a Cat*
. But the talkTo
function doesn't know that, until we "turn around the invokation" in Cat::talkTo( Animal* )
.
If animalCatPtr
is actually only an Animal
, then we will end up in base class Animal
, invoking Animal::talkTo( Cat* )
if that is available, or Animal::talkTo( Animal* )
if only that function is available.
If animalCatPtr
is actually a Cat
, then we will end up invoking Cat::talkTo( Cat* )
, which is the behavior we wanted.