I would like the experts here to have an opinion on the following problem. I would like to design a program in which derived classes from different base classed interact with each other. To make my point clear, I have constructed an example.
Imagine that I try to make a zoo. In this zoo we have animals, and we have fruits, which are my base classes. Only during runtime we know which animals we have, and which fruits. Assume that I have a monkey and a banana.
How do I let this monkey consume a banana in an elegant way, where eating a banana is a very unique skill of this monkey only? Note that I don't want a generic eat function, because I need in my design total freedom in the actions that a derived animal can perform.
This is the accompanying example:
#include <string>
#include <iostream>
class cfruit
{
};
class cbanana : public cfruit
{
};
class canimal
{
};
class cmonkey : public canimal
{
public:
int eatbanana(cbanana *) { std::cout << "BURP" << std::endl; }
};
int main()
{
cfruit *fruit;
canimal *animal;
// on runtime the animal and the fruit is decided, so we have to
// initialize it on the base pointer
// assume we get a monkey and a banana
fruit = new cbanana();
animal = new cmonkey();
// now, we would like our monkey to eat a banana, which we cannot do...
// UNLESS... we do something really UGLY
static_cast<cmonkey *>(animal)->eatbanana(static_cast<cbanana *>(fruit));
return 0;
}
You are asking us a way to violate the Liskov Principle "elegantly".
When you manipulate a mother class, you should not assume of the concrete derived class that is instanciated behind.
This is called bad design, coding smell.
If your class is indeed a monkey, and you want it to eat bananas: you should not manipulate it as an animal, but as a monkey.
A track to find a solution anyway could start this way:
As you explain, there is an implicit link between animals and their fruit. You could create a class Meal which goal is to manage this link explicitely.
struct Meal
{
virtual void consume() = 0;
}
Meal* factoryCookMonkeyMeal(Monkey& monkey, Banana& banana)
{
return new MealMonkey(monkey,banana);
}
struct MealMonkey : public Meal
{
Monkey& monkey;
Banana& banana;
virtual void consume(){ monkey.eat_banana(banana);};
}
Meal* factoryCookBirdMeal(Bird& bird, Cherry& cherry)
{
return new MealBird(bird,cherry);
}
struct MealBird : public Meal
{
Bird& bird;
Cherry& cherry;
virtual void consume(){ bird.eat_cherry(cherry);};
}
However you don't tell us precisely the way you determine the animal and the fruit... so that doesn't help... because it is this choice that knows the info that must be used for calling the good factoryMethod that creates the appropriate meal.
Related
I'm coming mostly from functional languages background and I have no idea how to do this sort of pattern well in object oriented languages.
Let's say I have some Animal classes and subclasses and an AnimalManager. I want an "add" method on the AnimalManager which has different behavior depending on whether I'm adding a Cat or a Dog. Something like this (in no particular language):
class Animal
class Cat : Animal
class Dog : Animal
class AnimalManager {
void add(Animal a) {
a match {
case Cat => // do something with cats
case Dog => // do different something with dogs
}
}
}
Now what if I'm using a language like C++ which does not support matching on type in this manner. Two solutions I could think of are:
Use dynamic_cast. However, I'm told dynamic cast should be avoided because it can lead to run-time errors, so this may be bad practice.
Use virtual functions. I could do something like the following (again no particular language, but you should get the gist):
class Animal {
virtual void beAdded(AnimalManager am)
}
class Cat : Animal {
void beAdded(AnimalManager am) {
am.doThingsWithCats(this)
}
}
class Dog : Animal {
void beAdded(AnimalManager am) {
am.doThingsWithDogs(this)
}
}
class AnimalManager {
void doThingsWithDogs(Dog d) {
// do something with dogs
}
void doThingWithCats(Cat d) {
// do something with cats
}
void add(Animal a) {
a.beAdded(this)
}
}
This is obviously extremely awkward and has other problems (now Animal needs to know about AnimalManager?).
What is the best way to do this sort of pattern in object-oriented languages? Is there some "design pattern" here I should know about?
I'll suggest you provide the real use case instead of metaphor because you might have a XY problem.
You may use RTTI here and there is another issue I want to elaborate.
Don't use void add(Animal a) which slices your object into just Animal and you will always get Animal instead of derived class Cat or Dog.
Use void add(Aniaml& a) to keep the object or use a (smart) pointer.
#include <iostream>
class Animal{
public:
// Read Item 7 in Scott Meyers' Effective C++ if you don't know why you need it
#include <iostream>
class Animal{
public:
virtual ~Animal(){};
};
class Cat : public Animal{
};
class Dog : public Animal{
};
class AnimalManager {
public:
#define REF < comment it to see what your code do
#ifdef REF
void add(Animal& a) {
#else
void add(Animal a) {
#endif
using std::cout;
using std::endl;
if(typeid(a) == typeid(Cat)){
cout << "Meow" << endl;
}else if(typeid(a) == typeid(Dog)){
cout << "Bark" << endl;
}else{
cout << "I'm just animal" << endl;
}
}
};
int main()
{
Dog d;
Cat a;
AnimalManager m;
m.add(d);
m.add(a);
}
Live demo
With reference
Bark
Meow
Pass by value
"I'm just animal
"I'm just animal
Consider I have a Plant class that has derived Fruit and Vegetable classes, and Fruit class has some more derived classes, like Orange and Apple, while Vegetable has derived Potato and Tomato. Assume, Plant has Plant::onConsume()=0; method:
class Plant
{
public:
virtual void onConsume(void)=0;
};
class Fruit:public Plant
{
};
class Orange:public Fruit
{
void onConsume(void)
{
// Do something specific here
}
};
class Apple:public Fruit
{
void onConsume(void)
{
// Do something specific here
}
};
class Vegetable:public Plant
{
};
class Potato:public Vegetable
{
void onConsume(void)
{
// Do something specific here
}
};
class Tomato:public Vegetable
{
void onConsume(void)
{
// Do something specific here
}
};
class Consumer
{
public:
void consume(Plant &p)
{
p.onConsume();
// Specific actions depending on actual p type here
// like send REST command to the remote host for Orange
// or draw a red square on the screen for Tomato
}
};
Suppose, I have a Consumer class with Consumer::consume(Plant) method. This "consume" method should perform different actions for different "Plants" instances/types, among calling Plant::onConsume() for any of "Plants". These action ain't directly related to the Plant class, require a lot of different additional actions and parameters, could literally be completely arbitrary, so cannot be implemented inside onConsume method.
What is the preferred method to implement this? As I understand, it is possible to implement some "Plant::getPlantType()=0" method, that would return plant type, but in this case I'm not sure what should it return. In case the returned value would be an enum, I'd need to change this enum each time I add a new derived class. And in any case, there's no control that multiple derived classes could return the same value.
Also, I'm aware there's a dynamic_cast conversion that returns nullptr if conversion could not be made, and typeid() operator that returns std::typeinfo (even with typeinfo::name()), which could be used in the switch() (it's just great for my case). But I'm afraid it could significally slow down the execution and make code heavier.
So, my question is, what is the preferred way in C++ to do that? maybe I just forgot about some simpler way to implement that?
A little update. Thank you for your explanations about inheritance, encapsulation etc! I supposed it's clear from my question, but it is not, I am sorry about that. So, please think about it, like I don't have an access to the whole Plant sources hierarchy, just need to implement this Consumer::onConsume(Plant). So I cannot add new specific methods in it. Or, also, it could be considered as a Plants library, that I have to write once, and make it usable for other devs. So, I could divide use cases/functionality into two parts: one that implemented "per class" in the Plant::onConsume() method, and second that is unknown yet and will differ depending on usage.
One option would be the visitor pattern, but this requires one function per type in some class. Basically you create a base class PlantVisitor with one Visit function per object type and pass add a virtual method to Plant that receives a PlantVisitor object and calls the corresponding function of the visitor passing itself as parameter:
class PlantVisitor
{
public:
virtual void Visit(Orange& orange) = 0;
virtual void Visit(Tomato& tomato) = 0;
...
};
class Plant
{
public:
virtual void Accept(PlantVisitor& visitor) = 0;
};
class Orange : public Plant
{
public:
void Accept(PlantVisitor& visitor) override
{
visitor.Visit(*this);
}
};
class Tomato : public Plant
{
public:
void Accept(PlantVisitor& visitor) override
{
visitor.Visit(*this);
}
};
This would allow you to do something like this:
class TypePrintVisitor : public PlantVisitor
{
public:
void Visit(Orange& orange) override
{
std::cout << "Orange\n";
}
void Visit(Tomato& tomato) override
{
std::cout << "Tomato\n";
}
};
std::vector<std::unique_ptr<Plant>> plants;
plants.emplace_back(std::make_unique<Orange>());
plants.emplace_back(std::make_unique<Tomato>());
TypePrintVisitor visitor;
for (size_t i = 0; i != plants.size(); ++i)
{
std::cout << "plant " << (i+1) << " is a ";
plants[i]->Accept(visitor);
}
Not sure the need for this does not indicate a design inefficiency though.
Btw: If you've got multiple visitors and do not necessarily want to implement logic for every single type in all of them, you could add default implementations in PlantVisitor that call the function for the supertype instead of specifying pure virtual functions.
Polymorphism is all about not having to know about a specific type. Usually your design is flawed if you discover having to detect a specific type explicitly.
At very first:
void Consumer::consume(Plant p)
does not work as intended! The Plant object is accepted by value, i. e. its bytes are copied one by one; however, only those of the Plant type, any others (those of derived types) are ignored and get lost within consume function – this is called object slicing.
Polymorphism only works with references or pointers.
Now assume you want to do something like the following (incomplete code!):
void Consumer::consume(Plant& p) // must be reference or pointer!
{
p.onConsume();
generalCode1();
if(/* p is apple */)
{
appleSpecific();
}
else if(/* p is orange */)
{
orangeSpecific();
}
generalCode2();
}
You don't want to decide yourself upon type, you let the Plant class do the stuff for you, which means you extend its interface appropriately:
class Plant
{
public:
virtual void onConsume() = 0;
virtual void specific() = 0;
};
The code of the consume function will now be changed to:
void Consumer::consume(Plant const& p) // must be reference or pointer!
{
p.onConsume();
generalCode1();
p.specific();
generalCode2();
}
You'll do so at any place you need specific behaviour (and specific is just a demo name, chose one that describes nicely what the function actually is intended to do).
p.onConsume();
generalCode1();
p.specific1();
generalCode2();
p.specific2();
generalCode3();
p.specific3();
generalCode4();
// ...
Of course you need now to provide appropriate implementations in your derived classes:
class Orange:public Fruit
{
void onConsume() override
{ }
void specific() override
{
orangeSpecific();
}
};
class Apple:public Fruit
{
void onConsume() override
{ }
void specific() override
{
appleSpecific();
}
};
Note the addition of override keyword, which protects you from accidentally creating overloaded functions instead actually overwriting in case of signature mismatch. It helps you, too, to locate all places of necessary changes if you discover having to change the function signature in the base class.
I am facing an OOP problem in GUI design, but let me illustrate it with animals example. Lets have following setup:
there is a base class Animal
any derived class can has-a Teeth
every animal with Teeth can Bite() <=> animals without Teeth cannot Bite()
every animal Bite() the same way (there is default implementation in Teeth class)
It is only natural for animal has-a Teeth, but now I need something like interface for has-a relationship. For example, if I have a vector of animals, how can I make every Bite() if they can?
std::vector<Animal *> animals;
animals.push_back(new dog());
animals.push_back(new fly());
animals.push_back(new cat());
void Unleash_the_hounds(std::vector<Animal *> animals)
{
//bite if you can!
}
I came up with several solutions but none seems to be perfectly fitting:
1.) every class with Teeth also implements interface IBiting. This solution, however, introduces a lot of code duplication, I would need to "implement" Bite() in every class:
class Cat : public Animal, public IBiting {
Teeth teeth;
public:
virtual void Bite() { teeth.Bite(); }
}
2.) Give every animal Teeth, but only allow some to use them. Note: syntax can be wrong - it is only illustration
class Animal{
static cosnt bool canBite = false;
Teeth teeth;
public:
void Bite() { this->canBite ? teeth.Bite() : return; }
}
class Cat {
static cosnt bool canBite = true;
}
3.) More inheritance - create class BitingAnimal and derive it. Well, this could work, but what if I needed derive (non)flying animals, some of them have teeth.
class Animal{}
class BitingAnimal : public Animal {
Teeth teeth;
}
and use as BitingAnimal.teeth.Bite()
4.) multiple inheritance. This often is discouraged, and impossible in most languages, plus it is not logical for Cat to be Teeth.
class Cat : public Animal, public Teeth {
}
5.) Enum of classes that can bite - weird only by sound of it.
Or am I only over-complicating it and missed something important?
An alternative that you didn't mention is to just provide an abstraction for the teeth, but implement the biting in the base class. This reduces the duplication because the derived classes only need to specify how to access the teeth instead of how to bite. By returning a pointer to the teeth, we can allow a null pointer to indicate that the animal has no teeth. Here is an example:
#include <vector>
struct Teeth {
void bite() { }
};
struct Animal {
virtual Teeth *teethPtr() = 0;
void biteIfYouCan() { if (teethPtr()) teethPtr()->bite(); }
};
struct Dog : Animal {
Teeth teeth;
Teeth *teethPtr() override { return &teeth; }
};
struct Fish : Animal {
Teeth *teethPtr() override { return nullptr; }
};
int main()
{
Dog dog;
Fish fish;
std::vector<Animal *> animals {&dog,&fish};
for (auto animal_ptr : animals) {
animal_ptr->biteIfYouCan();
}
}
1) Interface is good and you can add default implementation this way:
class IBiting { public virtual void bite() = 0 };
class HasTeeth, public IBiting { Teeth teeth; public:
virtual void bite() override { teeth.bite(); } };
for(Animal* a: animals) {
IBiting* it = dynamic_cast<IBiting*>(a);
if(it) it->bite(); }
1b) ...you can as well completly remove the interface and use only HasTeeth:
class HasTeeth { Teeth teeth; public:
void bite() { teeth.bite(); } };
for(Animal* a: animals) {
HasTeeth* it = dynamic_cast<HasTeeth*>(a);
if(it) it->bite(); }
2) Bloating Animal can be used if you don't want to use RTTI/dynamic_cast. You could make virtual void bite() with empty implementation on Animal and override it later (once adding Teeth). Not that much of coding if you insist not to use RTTI, but if you can use dynamic_cast, why not using it?
EDIT: The answer from Vaughn Cato is perfect for this - virtual/abstract teethPtr() (or getTeeth()) in Animal with short-cuts like biteIfYouCan(). Good for embedded world (microchips), but for PC, I still prefer dynamic_cast.
3) Virtual inheritance can help us with BitingAnimal vs. FlyingAnimal:
class BitingAnimal: public virtual Animal {
Teeth teeth; public void bite() { teeth.bite(); } };
class FlyingAnimal: public virtual Animal {
Wings wings; public void fly() { wings.fly(); } };
class FlyingBitingAnimal: /*public virtual Animal, */
public FlyingAnimal, public BitingAnimal {};
4) Joining Animal and Teeth has no sense unless you completely remove Teeth and replace it with HasTeeth or CanBite. Then it becomes my 1b.
5) That enum is another version of 2 - bloating animal. Not good.
But that leads me to alternative not using dynamic_cast: you can mimic it by capabilities (that enum, or flags on animal - bool can_bite) that can tell you, wich cast is safe. Then you can use multiple/virtual inheritance to mimic dynamic_cast (check capability first, cast next).
EDIT: Vaughn Cato's teethPtr() matches this as well (show me the teeth you can bite with if you have them) and does not need the cast.
Answer to comment:
In short: try to name a feature (capability, ability to do something, to provide something).
Long answer: Do you need Teeth and HasTeeth or single CanBite? Your 4th solution is not bad in the principle, but in naming and therefore other possibilities. All this was hypothetical. Interfaces are well known in other languages (single inheritance + interfaces), HasTeeth is something like C# IListSource with IList GetList() and bool ContainsList (for erasure) where the bite() is not there directly, but can be added by extension method:
static IEnumerator GetEnumerator(this IListSource it) {
if(!it.ContainsList) yield break;
foreach(object o in it.GetList()) yield return o; }
Here you can see, that I have achieved same thing with C# extension method as with C++ multiple inheritance. The name is is-a form - SourceOf. Can you share the real names from your GUI with us?
Example from C++ would be iostream = istream + ostream with virtual inheritance from ios. Again is-a naming.
Here are my comments to your solutions:
I agree with you that this will result in a lot of code duplication. Not cool.
This clearly isn't the best way. Using canBite flag is a symptome, that it can be done better.
Again, bad design - calling BitingAnimal.teeth.Bite() is a violation of Law of Demeter. Also, as you described - what if an Animal which is not BittingAnimal would like to bite?
As Mare Infinitus commented, in this approach your Cat is a Teeth. This is not entirely correct.
Enum of classes that can bite - you're right. This is weird :)
I'd suggest following approach: create IBiting interface and its implementation Biting in a mixin-like way:
class Bitting : public IBiting {
Teeth teeth;
public:
virtual void Bite() { teeth.Bite(); }
}
then, each class which can bite, will inherit from Biting "mixin":
class Cat : public Animal, public Biting {
}
This will be a multiple inheritance, of course, but, since Biting only implements a "Biting" functionality, it won't be so bad (no Diamond Problem).
The question boils down to what should happen if you call animal->bite() and that animal does not have teeth and cannot bite. One answer could be that all animals can bite. For cats it has an effect due to them having teeth whereas other animals such as butterflies can bite but nothing happens.
class Animal{
public:
virtual void bite(){}
};
class Cat : public Animal{
Teeth teeth;
void bite() override{
teeth.bite();
}
};
class Butterfly : public Animal{
};
In this approach you do need to write for every animal type extra how it bites if it can. It becomes a bit more tricky if you need other attributes like scream() and fly(). Yes cats can fly in this model, it is just that nothing at all happens when they do and butterflies can scream with a volume of zero.
Since there are a lot of animals who have teeth and they all bite the same way you could add a few specialized animals.
class BitingWithTeethAnimal : public Animal{
Teeth teeth;
void bite() override{
teeth.bite();
}
};
class Cat : public BitingWithTeethAnimal{
};
class Butterfly : public FlyingWithWingsAnimal{
};
Ideally you would be able to say something like class Pterodactyl : public BitingWithTeeth, FlyingWithWings, ScreamingWithVoice, Animal; without bloating Animal to a monster class but that is not possible in my implementation. The upside though is that you only implement the things you need and you never get confused when an animal can bite with its teeth and also with its beak since the implementation is in one function and not separated in different classes.
This answer is no longer valid, once we made clear that:
every animal with Teeth can Bite() <=> animals without Teeth cannot Bite()
This leads to less separation. There are better answers, but I have undeleted this one to show my thoughts about the design:
Original:
class Animal { public: virtual ~Animal() {} /* for RTTI */ };
class IBite { virtual void Bite() = 0; }; // interface
class Teeth: public IBite { public: void Bite() { ... } }; // implementation
class HasTeeth { protected: Teeth teeth; }; // part of thought process
class BiteWithTeeth: public HasTeeth, public IBite { // interface
public: void Bite() { teeth.Bite(); } }; // +implementation
class Cat: public Animal, public BiteWithTeeth {}; // final class
class Unknown: public Animal, public HashTeeth {}; // but no IBite - not allowed
The order above should make you think why. It involves using dynamic_cast to find the interface (solution will be different if you insist not using it). I prefer to separate things that are not related and find the smallest things (classes/interfaces) that are truly related (otherwise you will do that later when you find that you need it - if you ever need to separate bite from teeth).
class AnimalBitingWithTeeth: public Animal, public BiteWithTeeth {};
class AnimalWithTeethButNotBiting: public Animal, public HashTeeth {};
We need Animal as base class and IBite (or IBiting) to mark some feature. Other classes allow us to implement that feature (e.g. BiteWithTeeth) but allow other implementations as well.
Important question is: Can we have a chain where IBite will be included but we want to disable it then? We can reimplement (virtual) Bite with empty or add virtual bool CanBite() if we need to ask such question (instead of bite if you can). It is crutial to find correct questions (and features) in OOP to create good design.
See my second answer for the solution - multiple/virtual inheritance.
It's a code smell to put things into the same container that don't share something.
Query for the right container instead of query the class of it's capabilities.
If you really want to have a single creating instance use a helper class. But try to use interfaces for classes that have something in common. Imagine if you have 5000 animal types and two of them can bite. Do you really want to look through each of them to go an check each of them for teeth? You already know you only have two dogs at the time you acquire them.
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
struct Animal { virtual ~Animal() {} }; // used to tag elements
struct Biting : public Animal { virtual void bite() = 0; };
struct Flying : public Animal { virtual void fly() = 0; };
struct Bird : public Flying {
virtual void fly() override { cout << "Fly\n"; }
};
struct Dog : public Biting {
virtual void bite() override { cout << "Bite\n"; }
};
struct World {
void populate(Animal *animal) {
Biting *b = dynamic_cast<Biting *>(animal);
if (b != nullptr) {
Biters.push_back(b);
return;
}
Flying *f = dynamic_cast<Flying *>(animal);
if (f != nullptr) {
Flyers.push_back(f);
return;
}
}
std::vector<Biting *> Biters;
std::vector<Flying *> Flyers;
};
class Schaefer : public Dog { };
class Pitbull : public Dog { };
class KingFisher : public Bird { };
class WoodPecker : public Bird { };
int main(int argc, char **argv) {
World w;
Schaefer s;
Pitbull p;
KingFisher k;
WoodPecker wp;
w.populate(&s);
w.populate(&p);
w.populate(&k);
w.populate(&wp);
for (auto &i : w.Biters) {
i->bite();
}
for (auto &i : w.Flyers) {
i->fly();
}
return 0;
}
You have an animal Shelter. Shelter can store variable number of Animals. You put many Animals (Dogs and Cats) into the shelter.
Then you tell the employee to randomly select and bring you few Animals. You don't know what type of an Animal he selected.
You tell them to Speak. Some of them goes "bark", some goes "meow".
Important! Dogs can fetch and Cats can't.
If you know for sure you've selected a Dog it should be able to fetch right away (without upcasting from Animal to Dog for example)
How to implement this kind of logic? (preferably without boost::any)
Here is a partially working example: http://ideone.com/kR4788
#include <iostream>
#include <map>
using namespace std;
class Animal {};
class Shelter {
private:
std::map<int, Animal*> animals;
public:
void Add(Animal* animal) {
animals[animals.size()] = animal;
};
Animal* Select(int index) {
return animals[index];
}
};
class Dog: public Animal {
public:
void Speak() { cout << "bark" << endl; }
void Fetch() {}
};
class Cat: public Animal {
public:
void Speak() { cout << "meow" << endl; }
};
Shelter shelter;
int main() {
shelter.Add(new Cat());
shelter.Add(new Dog());
// I'd like to make it work like this
//
// shelter.Select(0)->Speak(); /* meow */
// shelter.Select(1)->Speak(); /* bark */
//
// Like below but without upcasting to given animal
((Cat*) shelter.Select(0))->Speak();
((Dog*) shelter.Select(1))->Speak();
// I know under index 1 is a Dog so it can fetch!
//
// shelter.Select(1)->Fetch(); /* no segfault */
//
// Like below but without upcasting to given animal
((Dog*) shelter.Select(1))->Fetch();
return 0;
}
Edit:
You can try to use a dynamic_cast to cast your Animal object into a Dog and then call the fetch method:
Dog *foo = dynamic_cast<Dog*>(shelter.Select(1));
if (foo) {
foo->Fetch();
}
If the dynamic_cast fails, it will return null so make sure to check if the object is not null before using it. For more information on dynamic_cast, check here.
You can add a virtual function to your Animal interface:
class Animal {
public:
virtual void speak();
};
Also, on an unrelated note, your speak method doesn't seem to be modifying the object so you should consider putting them as const:
class Animal {
public:
virtual void speak() const;
};
You can find more information on const-correctness here.
As Aliou noticed speak should be declared virtual in Animal, otherwise the hierarchy is rather useless, or, in other words, there is no polymorphism.
Testing if an Animal is a Dog (and upcasting at the same time) with dynamic_cast<Dog*> is an option to consider. Not pretty, but it works.
Dog *dog = dynamic_cast<Dog*> shelter.Select(1);
if (dog) dog->Fetch();
(dynamic_cast to a pointer never throws, as others suggested...)
Another solution is to define virtual Fetch in Animal, perhaps as a NOP ({}), so you don't have to define it in animals which don't fetch.
As per request I post my comment as an answer. The full source is in Ideone:
In class Animal:
class Animal {
public:
virtual void Speak() const = 0;
virtual void Fetch() const { cout << "This animal can't fetch" << endl;};
virtual ~Animal(){ }
};
The virtual destructor is needed to ensure that the correct destructor is called for objects that derive from the base class. Without the virtual destructor only the base class destructor would be called and not the destructor for the derived object.
In Dog:
void Fetch() const { cout << "fetch" << endl; }
And in main:
shelter.Select(0)->Speak();
shelter.Select(1)->Speak();
shelter.Select(0)->Fetch();
shelter.Select(1)->Fetch();
You didn't ask the employee to return only animals which could fetch, therefore you must check (cast) each animal can fetch.
The alternative is to add a dummy fetch function to animal, which doesn't do anything except for dogs.
class Animal
{
};
class Herbivore:Animal
{
void eat();
};
class Carnivore:Animal
{
void eat();
};
class Food
{
bool bMeat;
bool bVegeable;
};
I start out this class and all of a sudden I don't know what to do to with the class Food, as I would like to print out the correct food type each "kind" of animal favors most.
Sorry my food class size is small but I can't delete it as my whole program requires it to distinguish the food type. I will not mind if you suggest a different solution.
Since this is homework, I'm not going to post a code snippet, I'll just try to explain (and by trees, I assume you mean inheritance).
I see that you've fixed the animals not inheriting from Animal which is good. However, to incorporate Food into the mix, you probably want to have a member of Animal (so every subclass of Animal has to have it) that is a Food called favouriteFood or something similar, which is initialized in the constructor of each subclass of Animal to that animal's favourite food.
The second thing I think you'll want to do is to make the member function eat both virtual and part of Animal so that each subclass of Animal has that member (and virtual so that when you call the function through an Animal* or &, it will call the correct version). Then make eat have one parameter which is a Food, the food they are eating.
Try something like bool eat(Food & food). In eat you can then check if your animal likes it and either return false or consume the food and return true. It might also make sense to throw a bad_food exception instead of the return value.
Here's what I would try:
class Food;
class Vegetable : Food { ; };
class Meat : Food { ; }
struct Animal
{
virtual void eat(const Food& f)
{;} // Stubbed.
};
struct Herbivore : Animal
{
virtual void eat(const Vegetable&) = 0;
};
struct Carnivore : Animal
{
virtual void eat(const Meat&) = 0;
};
struct Omnivore : Animal
{
void eat(const Food& f)
{ cout << "I'm not picky.\n"; }
};
I suggest you look up concepts such as double dispatch and Visitor Design Pattern.