A more object-oriented approach would consist of relying on polymorphism instead of continuously switching on an enumerator value representing a type.
To follow this approach, first, define an abstract class, Animal
, that specifies the member functions its subclasses should implement:
class Animal {
public:
virtual std::string GetGermanTranslation() const = 0;
virtual float GetMaxSpeed() const = 0;
virtual ~Animal() = default;
};
Then, publicly derive from this class and override the virtual member functions GetGermanTranslation()
and GetMaxSpeed()
.
For example, for Cat
:
class Cat: public Animal {
public:
std::string GetGermanTranslation() const override { return "Katze"; };
float GetMaxSpeed() const override { return 30; };
};
Then, similarly for Dog
:
class Dog: public Animal {
public:
std::string GetGermanTranslation() const override { return "Hund"; };
float GetMaxSpeed() const override { return 40; };
};
You can analogously define the Fish
class.
Finally, having a pointer or reference to an Animal
object, you just call the corresponding virtual member functions:
void displayAnimal(const Animal& animal) {
std::cout << "The " << animal.GetGermanTranslation();
std::cout << " runs at " << animal.GetMaxSpeed() << '\n';
}
As you can see, there is no more switching on an enumerator that represents a type for distinguishing the different animals.
You can call this function, displayAnimal()
, with different Animal
objects:
auto cat = std::make_unique<Cat>();
displayAnimal(*cat);
auto dog = std::make_unique<Dog>();
displayAnimal(*dog);