According to Thinking in C++
"You cannot modify the return type of a virtual function during
overriding.but there is a special case in which you can slightly
modify the return type. If you¡¯re returning a pointer or a reference to a
base class, then the overridden version of the function may
return a pointer or reference to a class derived from what the base
returns." And here's the example:
class PetFood
{
public:
virtual string foodType() const = 0;
};
class Pet
{
public:
virtual string type() const = 0;
virtual PetFood* eats() = 0;
};
class Bird : public Pet
{
public:
string type() const { return "Bird"; }
class BirdFood : public PetFood
{
public:
string foodType() const
{
return "Bird food";
}
};
// Upcast to base type:
PetFood* eats() { return &bf; }
private:
BirdFood bf;
};
class Cat : public Pet
{
public:
string type() const { return "Cat"; }
class CatFood : public PetFood
{
public:
string foodType() const { return "Birds"; }
};
// Return exact type instead:
CatFood* eats() { return &cf; }
private:
CatFood cf;
};
int main()
{
Bird b;
Cat c;
Pet* p[] = { &b, &c, };
for(int i = 0; i < sizeof p / sizeof *p; i++)
cout << p[i]->type() << " eats "
<< p[i]->eats()->foodType() << endl;
// Can return the exact type:
Cat::CatFood* cf = c.eats();
Bird::BirdFood* bf;
// Cannot return the exact type:
//! bf = b.eats();
// Must downcast:
bf = dynamic_cast<Bird::BirdFood*>(b.eats());
}
What annoying me is that once I get code above compiled, I get a compiler
error saying
"overriding virtual function differs from 'Pet::eats' only by return type or
calling convention" which is for "CatFood* eats() { return &cf; }"
But this differ is author's intension, How's that was flagged as an error?