[英]How to use dynamic_cast in if statement
So I've got a simple task to do. 所以我要做一个简单的任务。 There are 3 classes derived from one base class. 从一个基类派生3个类。 They're quite simple and will be provided below. 它们非常简单,将在下面提供。 What I need to do is create a new class called PolymorphicAnimal
, that'll be able to behave just as any other animal
derived from the Animal
base class. 我需要做的是创建一个名为PolymorphicAnimal
的新类,该类的行为就像从Animal
基类派生的任何其他animal
。 To be exact, all they need to do is display the right text after method SoundOff
is called. 确切地说,他们所需要做的就是在调用SoundOff
方法之后显示正确的文本。 I'm guessing I need to use dynamic_cast
here. 我猜我需要在这里使用dynamic_cast
。 My question is, what's the right syntax for using dynamic_cast
as an if
statement, and do all the derived classes need to have at least one virtual method as well? 我的问题是,将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))
}
};
The line if(std::dynamic_cast...
generates compiler errors: 该行if(std::dynamic_cast...
生成编译器错误:
syntax error '<', illegal token on the right side of ::
and expected an identifier
syntax error '<', illegal token on the right side of ::
并且expected an identifier
dynamic_cast
is almost always a hack. dynamic_cast
几乎总是hack。
Why don't you add another virtual method to Animal
, and then have Dog
, Cat
and Cow
override it in the usual way? 为什么不向Animal
添加另一个虚拟方法,然后用通常的方法让Dog
, Cat
和Cow
覆盖它呢? Or don't you control these classes? 还是您不控制这些课程?
In C++ you can declare a variable in the conditional of an if
, which is a powerful feature that you can exploit here. 在C ++中,您可以在if
的条件下声明变量,这是可以在此处利用的强大功能。 So, 所以,
if (auto kitty = dynamic_cast<const Cat*>(&a)){
// kitty is not nullptr
}
Notes: 笔记:
dynamic_cast
is a keyword ; dynamic_cast
是一个关键字 ; do drop the std::
确实删除了std::
dynamic_cast
. 我使用了一个指针dynamic_cast
。 The reference alternative is impractical as you can't, in general, expect an implicit conversion of a reference type to a bool
type, and if a reference cast fails an exception is thrown. 引用替代是不切实际的,因为您通常不能期望将引用类型隐式转换为bool
类型,并且如果引用强制转换失败,则会引发异常。 Whereas virtual methods or visitor might be more appropriated, you might use something like: 尽管虚拟方法或访问者可能更适合,但您可以使用类似以下内容的方法:
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
} // ...
}
It is very unclear what exactly the PolymorphicAnimal should do. 尚不清楚PolymorphicAnimal应该做什么。 Somehow you need to tell PolymorphicAnimal how to behave, right? 您需要以某种方式告诉PolymorphicAnimal如何表现,对吗? So, I'm guessing it's more like a Factory than a derived class. 因此,我猜它更像是工厂而不是派生类。
Something like this: 像这样:
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();
}
}
Normally, you shouldn't need to do if (something dynamic_cast something) in a normal program. 通常,您不需要在常规程序中执行if(某些内容为dynamic_cast内容)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.