简体   繁体   English

如何在if语句中使用dynamic_cast

[英]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添加另一个虚拟方法,然后用通常的方法让DogCatCow覆盖它呢? 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: 笔记:

  1. dynamic_cast is a keyword ; dynamic_cast是一个关键字 do drop the std:: 确实删除了std::
  2. I've used a pointer 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM