避免复制开关声明

问题描述

可以将此代码重构以避免复制switch语句吗?

EXISTS

很明显,这是一个玩具示例,我的实际枚举类更大。

解决方法

一种更加面向对象的方法将包括依靠多态性而不是连续打开表示类型的枚举器值。

要遵循这种方法,首先定义一个抽象类Animal,该抽象类指定其子类应实现的成员函数:

class Animal {
public:
    virtual std::string GetGermanTranslation() const = 0;
    virtual float GetMaxSpeed() const = 0;
    virtual ~Animal() = default;
};

然后,从该类公开派生并覆盖虚拟成员函数GetGermanTranslation()GetMaxSpeed()

例如,对于Cat

class Cat: public Animal {
public:
   std::string GetGermanTranslation() const override { return "Katze"; };
   float GetMaxSpeed() const override  { return 30; };
};

然后,类似Dog

class Dog: public Animal {
public:
   std::string GetGermanTranslation() const override { return "Hund"; };
   float GetMaxSpeed() const override  { return 40; };
};

您可以类似地定义Fish类。

最后,有了指向Animal对象的指针或引用,您只需调用相应的虚拟成员函数:

void displayAnimal(const Animal& animal) {
   std::cout << "The " << animal.GetGermanTranslation();
   std::cout << " runs at " << animal.GetMaxSpeed() << '\n';
}

如您所见,不再需要打开代表区分不同动物的类型的枚举器。

您可以使用不同的displayAnimal()对象来调用此函数Animal

auto cat = std::make_unique<Cat>();
displayAnimal(*cat);

auto dog = std::make_unique<Dog>();
displayAnimal(*dog);
,

如果没有另外指定,则枚举类型中的第一个枚举数的值为0,而后续枚举数的值比其上一个枚举数大。因此,

enum Animal
{ Cat,Dog,Fish};

Cat的值为0,Dog的值为1,Fish的值为2。要将这些值映射到其他值集,只需使用它们作为数组索引:

int max_speed[] = {
    30,40,15
};

const char* german_name[] = {
    "Katze","Hund","Fische"
};

现在,您可以编写max_speed[Cat]german_name[Dog]之类的东西。

请注意,字符串文字位于引号内,例如"Katze",而不是问题中的单引号。多个字符周围的单引号会创建一个时髦的东西,称为“多字符文字”。它们几乎没有用。