Can anyone explain the output of the following code?
#include <iostream>
#include <string>
class Animal
{
public:
Animal(const std::string & name) : _name(name) { }
~Animal() { }
virtual void printMessage() const
{
std::cout << "Hello, I'm " << _name << std::endl;
}
private:
std::string _name;
// other operators and stuff
};
class Cow : public Animal
{
public:
Cow(const std::string & name) : Animal(name) { }
~Cow() { }
virtual void printMessage()
{
Animal::printMessage();
std::cout << "and moo " << std::endl;
}
};
int main() {
Cow cow("bill");
Animal * animal = &cow;
cow.printMessage();
animal->printMessage();
}
The output is
Hello, I'm bill
and moo
Hello, I'm bill
I don't understand why. The pointer animal points at an object of type Cow. printMessage is a virtual function. Why isn't the implementation of the Cow class the one that is called?
Cow
isn't overriding the virtual function from Animal
because it has a different signature. What's actually happening is that Cow
is hiding the function in Animal
.
The result of this is that calling printMessage
on an Animal
will just use the version in Animal
, regardless of the one in Cow
(it isn't overriding it), but calling it from Cow
will use the one in Cow
(because it hides the one from Animal
).
To fix this, remove the const
in Animal
, or add the const
in Cow
.
In C++ 2011, you will be able to use the override
keyword to avoid subtle traps like this:
class Cow : public Animal
{
public:
Cow(const std::string & name) : Animal(name) { }
~Cow() { }
virtual void printMessage() override
{
Animal::printMessage();
std::cout << "and moo " << std::endl;
}
};
Notice the added override
after printMessage()
. This will cause the compiler to emit an error if printMessage
doesn't actually override a base class version. In this case, you would get the error.