所以我要做一个简单的任务。从一个基类派生3个类。它们非常简单,将在下面提供。
我需要做的是创建一个名为PolymorphicAnimal
的新类,该类的行为将与从animal
基类派生的其他任何Animal
一样。
确切地说,他们要做的就是在调用方法SoundOff
之后显示正确的文本。我猜我需要在这里使用dynamic_cast
。我的问题是,将dynamic_cast
用作if
语句的正确语法是什么,并且所有派生类也需要至少有一个虚拟方法吗?
#include "stdafx.h"
#include <iostream>
#include <string>
class Animal {
public:
virtual std::string SoundOff() = 0;
};
class Dog : public Animal {
std::string SoundOff() override { return "Woof"; }
};
class Cat : public Animal {
std::string SoundOff() override { return "Meow"; }
};
class Cow : public Animal {
std::string SoundOff() override { return "Muu"; }
};
class PolymorphicAnimal : public Animal {
std::string sound;
public:
PolymorphicAnimal(const Animal &a) {
if(std::dynamic_cast<Cat*>(a))
}
};
第if(std::dynamic_cast...
行会产生编译器错误:
syntax error '<', illegal token on the right side of ::
和expected an identifier
答案 0 :(得分:5)
dynamic_cast
几乎总是黑客。
为什么不向Animal
添加另一个虚拟方法,然后以通常的方式覆盖Dog
,Cat
和Cow
?还是您不控制这些课程?
答案 1 :(得分:2)
在C ++中,您可以在if
的条件下声明变量,这是您可以在此处利用的强大功能。所以,
if (auto kitty = dynamic_cast<const Cat*>(&a)){
// kitty is not nullptr
}
注意:
dynamic_cast
是关键字;确实放下std::
dynamic_cast
。引用替代是不切实际的,因为您通常不能期望将引用类型隐式转换为bool
类型,并且如果引用强制转换失败,则会引发异常。答案 2 :(得分:0)
虽然虚拟方法或访问者可能更适合,但您可以使用类似的方法:
PolymorphicAnimal(const Animal &a) {
if (const auto* cat = dynamic_cast<const Cat*>(&a)) {
// use cat
} else if (const auto* dog = dynamic_cast<const Dog*>(&a)) {
// use dog
} // ...
}
答案 3 :(得分:0)
目前还不清楚PolymorphicAnimal应该做什么。您需要以某种方式告诉PolymorphicAnimal如何表现,对吗?因此,我猜它更像是工厂而不是派生类。
类似这样的东西:
class PolymorphicAnimal : Animal
{
private:
Animal *animal;
public:
PolymorphicAnimal(int type)
{
if (type == Type_Cat) // Type_Cat is an enum for example
{
animal = new Cat();
}
// ...add other types here
}
std::string SoundOff()
{
return animal->SoundOff();
}
}
通常,您不需要在常规程序中执行if(某些内容为dynamic_cast内容)。