Iva*_*ana 3 c++ boilerplate switch-statement
可以重构这段代码以避免复制 switch 语句吗?
enum class Animal
{ Cat, Dog, Fish};
float GetMaxSpeed(Animal a)
{
switch (a)
{
case Animal::Cat:
return 30;
case Animal::Dog:
return 40;
case Animal::Fish:
return 15;
}
}
string GetGermanTranslation(Animal a)
{
switch (a)
{
case Animal::Cat:
return "Katze";
case Animal::Dog:
return "Hund";
case Animal::Fish:
return "Fische";
}
}
Run Code Online (Sandbox Code Playgroud)
显然,这是一个玩具示例,我真正的枚举类要大得多。
更面向对象的方法将包括依赖多态性,而不是连续切换表示类型的枚举器值。
要遵循这种方法,首先,定义一个抽象类,Animal,指定其子类应实现的成员函数:
class Animal {
public:
virtual std::string GetGermanTranslation() const = 0;
virtual float GetMaxSpeed() const = 0;
virtual ~Animal() = default;
};
Run Code Online (Sandbox Code Playgroud)
然后,从此类公开派生并覆盖虚拟成员函数GetGermanTranslation()和GetMaxSpeed()。
例如,对于Cat:
class Cat: public Animal {
public:
std::string GetGermanTranslation() const override { return "Katze"; };
float GetMaxSpeed() const override { return 30; };
};
Run Code Online (Sandbox Code Playgroud)
然后,对于Dog:
class Dog: public Animal {
public:
std::string GetGermanTranslation() const override { return "Hund"; };
float GetMaxSpeed() const override { return 40; };
};
Run Code Online (Sandbox Code Playgroud)
您可以类似地定义Fish类。
最后,有了指向Animal对象的指针或引用,您只需调用相应的虚拟成员函数:
void displayAnimal(const Animal& animal) {
std::cout << "The " << animal.GetGermanTranslation();
std::cout << " runs at " << animal.GetMaxSpeed() << '\n';
}
Run Code Online (Sandbox Code Playgroud)
如您所见,不再需要打开代表用于区分不同动物的类型的枚举器。
您可以displayAnimal()使用不同的Animal对象调用此函数:
auto cat = std::make_unique<Cat>();
displayAnimal(*cat);
auto dog = std::make_unique<Dog>();
displayAnimal(*dog);
Run Code Online (Sandbox Code Playgroud)