【问题标题】:How to use dynamic_cast in if statement如何在 if 语句中使用 dynamic_cast
【发布时间】:2018-12-11 13:12:27
【问题描述】:

所以我有一个简单的任务要做。从一个基类派生出 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 '&lt;', illegal token on the right side of ::expected an identifier

【问题讨论】:

  • if(std::dynamic_cast&lt;Cat*&gt;(a)) 有什么问题?
  • @stetoc 语法错误'dynamic_cast 一致)
  • 您不能将对象转换为指针,您需要在动态转换中基本上在a 之前添加&amp;,以便传递对象的地址
  • 使用if(std::dynamic_cast&lt;Cat*&gt;(&amp;a)

标签: c++ class base-class dynamic-cast


【解决方案1】:

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

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

注意事项:

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

【讨论】:

  • 我在尝试你的代码,但它不起作用,然后我意识到我错过了const,然后它就起作用了。这正是我一直在寻找的。谢谢!
  • 另外,只是作为古玩,没有const
  • @MelvinBrooks:出于兴趣,什么语法不起作用?
  • 啊,我明白了,是的,您需要在 dynamic_cast 中使用 &lt;const Cat*&gt;,因为不允许 dynamic_cast 抛弃 const-ness,为此需要 const_cast,并注意所有注意事项和这样的演员一起去。
  • @Bathsheba 我想是因为Cat 是作为const 引用传入的。
【解决方案2】:

dynamic_cast 几乎总是一个 hack。

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

【讨论】:

  • 这是我考试中经常出现的一项任务,它的得分很高,教授希望表明我们知道何时以及如何使用dynamic_cast跨度>
  • 好吧,好吧,如果你别无选择......那么现在你知道怎么做了,'when' 是......'never' :)
  • ͏+͏1͏͏͏͏͏͏͏͏͏͏͏͏͏ 如果曲线球答案包含出色的建议,则没有任何问题,这一点就是这样做的。
  • @Bathsheba 谢谢,我很荣幸。曲线球答案是我的一个商标。并不总是有效,但是,你知道的。
  • 当然您现在可以轻松添加课程BadgerGerbilWeasel
【解决方案3】:

目前还不清楚 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 (something dynamic_cast something)。

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

      猜你喜欢
      • 2017-08-30
      • 1970-01-01
      • 2015-01-26
      • 2020-06-23
      • 2020-12-02
      • 1970-01-01
      • 1970-01-01
      • 2020-09-09
      • 2012-09-07
      相关资源
      最近更新 更多