I'm having a rough time with a particular C++ inheritance problem. Apologies if it got answered before, but I just couldn't find a proper answer. Say we have two abstract classes, one using the other as argument type for one of the pure virtual functions:
class Food {
public:
int calories=0;
virtual void set_calories(int cal)=0;
}
class Animal {
public:
int eaten_calories=0;
virtual void eat_food(Food &f)=0;
}
Now, we create a derived class for each, and we instantiate a virtual function with arguments of type the derived class:
class Vegetables: public Food{
public:
void set_calories(int cal){calories=cal;}
}
class Cow: public Animal{
public:
void eat_food(Vegetables &v){this->eaten_calories += v.calories;}
}
The problem with this is that the function eat_food
requires a signature with the abstract class Food
, or else a Cow()
object creation won't compile, complaining that Cow
is an abstract class because no suitable implementation of eat_food(Food f)
was found.
Update: An additional constraint I seek for the implementation is that a second class Meat: public Food
should not be usable with Cow::eat_food(f)
. In short, just setting Cow::eat_food(Food f)
and casting to Vegetables
wouldn't cut it.
What is the best way to overcome this error?
So far I have found two options:
- Creating an
eat_food(Food f)
implementation inCow
with atry/catch
to check iff
can be safely casted toVegetables
, and then callingeat_food(Vegetables v)
. PROBLEM: if you have 50 virtual functions, this forces you to write 50 additional function implementations inCow
. - Turn the
Animal
into a Template classAnimal<T>
, and instantiate it with each of the derived classes ofFood
to define the animals (e.g.,class Cow: public Animal<Vegetables>
). *PROBLEM: you can no longer define anAnimal*
pointer to hold an undefined animal with not known type.
Is there any viable/stylish alternative to these two? Maybe a software pattern of some kind?
Aucun commentaire:
Enregistrer un commentaire