使用 dynamic_cast 运算符
Using the dynamic_cast operator
我正在尝试了解动态类型转换。
如何使用 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);
}
我会针对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)) {
}*/
}
由于以下几个原因而明显错误:
animals
是一个向量
- 如果您想要一个单独的元素,那么因为
&animals[i]
(i = [0..animals.size()])
是指向指针 (Animal**
) 的指针
- 因为
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
而有些则没有?
我正在尝试了解动态类型转换。 如何使用 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);
}
我会针对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)) {
}*/
}
由于以下几个原因而明显错误:
animals
是一个向量- 如果您想要一个单独的元素,那么因为
&animals[i]
(i = [0..animals.size()])
是指向指针 (Animal**
) 的指针
- 因为
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
而有些则没有?