c++ - 使用 dynamic_cast 运算符

我试图了解动态类型转换。如何使用 dynamic_cast 正确实现 DrawAnimals 和 Talk To Animals 功能?

DrawAnimals 绘制可以绘制的动物。这样的动物实现了 Drawable 接口。 TalkToAnimals 与会说话的动物进行对话,即它们实现了 Speakable 接口。

class Speakable {
public:
    virtual ~Speakable() = default;
    virtual void Speak(ostream& out) const = 0;
};

class Drawable {
public:
    virtual ~Drawable() = default;
    virtual void Draw(ostream& out) const = 0;
};

class Animal {
public:
    virtual ~Animal() = default;
    void Eat(string_view food) {
        cout << GetType() << " is eating "sv << food << endl;
        ++energy_;
    }
    virtual string GetType() const = 0;

private:
    int energy_ = 100;
};

class Bug : public Animal, public Drawable {
public:
    string GetType() const override {
        return "bug"s;
    }
    void Draw(ostream& out) const override {
        out << "(-0_0-)"sv << endl;
    }
};

class Cat : public Animal, public Speakable, public Drawable {
public:
    void Speak(ostream& out) const override {
        out << "Meow-meow"sv << endl;
    }
    void Draw(ostream& out) const override {
        out << "(^w^)"sv << endl;
    }
    string GetType() const override {
        return "cat"s;
    }
};

void DrawAnimals(const std::vector<const Animal*>& animals, ostream& out) {
    /*if (const Animal* r = dynamic_cast<const Animal*>(&animals)) {

    } else if (const Bug* c = dynamic_cast<const Bug*>(&animals)) {

    }*/
}

void TalkToAnimals(const std::vector<const Animal*> animals, ostream& out) {
    //?
}

void PlayWithAnimals(const std::vector<const Animal*> animals, ostream& out) {
    TalkToAnimals(animals, out);
    DrawAnimals(animals, out);
}

int main() {
    Cat cat;
    Bug bug;
    vector<const Animal*> animals{&cat, &bug};
    PlayWithAnimals(animals, cerr);
}

回答1

我将为 DrawAnimals 进行解释,您可以自行扩展到其他功能。

你在这里做了什么:

void DrawAnimals(const std::vector<const Animal*>& animals, ostream& out) {
    /*if (const Animal* r = dynamic_cast<const Animal*>(&animals)) {

    } else if (const Bug* c = dynamic_cast<const Bug*>(&animals)) {

    }*/
}

完全错误有几个原因:

  1. animals 是一个向量
  2. 如果您打算使用单个元素,那么因为 &animals[i] (i = [0..animals.size()]) 是指向指针 (Animal**) 的指针
  3. 因为 dynamic_cast<const Animal*>(animals[i]) (i = [0..animals.size()]) 是身份。

您需要使用向量的每个单独元素:

void DrawAnimals(const std::vector<const Animal*>& animals, ostream& out) {
    for (auto animal : animals) {
        if (const Drawable* r = dynamic_cast<const Drawable*>(animal)) {
            // this animal is Drawable

        } else if (const Bug* c = dynamic_cast<const Bug*>(animal)) {
            // this animal is a Bug
            // only issue here: Bugs are also Drawable
            // so this code will never be reached
        }
    }
}

问题:为什么有些动物是 Drawable 而有些不是?

相似文章

随机推荐

最新文章