如何在 if 语句中使用 dynamic_cast

How to use dynamic_cast in if statement

所以我有一个简单的任务要做。有 3 个 class 派生自一个碱基 class。它们非常简单,将在下面提供。 我需要做的是创建一个名为 PolymorphicAnimal 的新 class,它将能够像从 Animal 基础 class 派生的任何其他 animal 一样工作]. 确切地说,他们需要做的就是在调用方法 SoundOff 之后显示正确的文本。我猜我需要在这里使用 dynamic_cast 。我的问题是,将 dynamic_cast 用作 if 语句的正确语法是什么,所有派生的 classes 是否也需要至少有一个虚拟方法?

#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

在 C++ 中,您可以在 if 的条件中声明一个变量,这是一个您可以在这里利用的强大功能。所以,

if (auto kitty = dynamic_cast<const Cat*>(&a)){
    // kitty is not nullptr
}

备注:

  1. dynamic_cast 是一个 关键字 ;删除 std::
  2. 我用过指针dynamic_cast。引用替代方案是不切实际的,因为您通常不能期望将引用类型隐式转换为 bool 类型,如果引用转换失败,则会抛出异常。

虽然虚拟方法或访问者可能更合适,但您可以使用类似的东西:

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
    } // ...
}

dynamic_cast 几乎总是黑客。

为什么不向 Animal 添加另一个虚拟方法,然后让 DogCatCow 以通常的方式覆盖它?还是你不控制这些类?

目前还不清楚 PolymorphicAnimal 究竟应该做什么。您需要以某种方式告诉 PolymorphicAnimal 如何行为,对吗?所以,我猜它更像是一个工厂而不是派生的 class.

像这样:

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 (something dynamic_cast something)。