动态向下转型到抽象类(C++)

9

我正在尝试学习一些Java中的面向对象编程方面在C++中的应用。然而,在使用dynamic_cast时,我遇到了一些困难,因为这个问题在Java中使用instanceof。

我有一个基类Cell和一个派生(抽象)类Obstacle。我已经这样定义了:Obstacle : public Cell,并且Obstacle包含一个纯虚析构函数。现在,在Cell类中,我想要实现一个方法bool Cell::isAccesible()。我已经按如下方式实现了它:

bool Cell::isAccessible() {

    Obstacle *obs = dynamic_cast<Obstacle*>(this);

    if (obs != NULL) return false;
    return true;
}

然而我收到了以下错误信息:
"the operand of a runtime dynamic_cast must have a polymorphic class type"
我的实现方式有什么问题?请给予指导,感谢。

这与Visual Studio有关吗?是他们的错误吗?(我问这个因为标签) - keyser
我只是在使用Visual Studio编写代码。我在编码过程中遇到了错误,也在编译时遇到了错误(C2683)。 - tim_a
1
你为什么在Cell方法中将Cell转换为obstacle? - atoMerz
3
这似乎是一个复杂的解决问题的方式。如果“isAccessible”是一个虚方法,那么“Obstacle”可以重写它并简单地返回false,这个问题就不再存在了。 - YoungJohn
1
我不知道你想做什么,但错误是因为你的Cell类不具有多态性,即它没有任何虚方法。如果你在Cell中添加一个虚方法,你的代码应该可以编译。 - atoMerz
1
在Java中使用instanceof或在C++中使用dynamic_cast来执行类型切换是你应该避免的。这会创建循环依赖,因为基类需要知道派生类的信息,反之亦然。 - David Rodríguez - dribeas
2个回答

17

为了使用dynamic_cast,Cell类必须至少有一个虚函数。另外,如果Cell是您的基类,则应该有一个虚析构函数。

您应该将isAccessible函数设为虚函数,并在Obstacle中重写它以返回false。


请问您能否详细说明为什么需要虚析构函数? - mradul dubey
@mraduldubey https://dev59.com/IHRB5IYBdhLWcg3w77on何时使用虚析构函数 - Neil Kirk

4

你的做法有些不妥。通常情况下,在基类中不需要将类型转换为其子类型 。如果确实需要,那么很可能是设计错误。在你的情况下,代码应该如下所示。

virtual bool Cell:: isAccessible()
{
  return true;
}

bool Obstacle::isAccessible()
{
  return false;
}

你出现错误的原因是 Cell 类没有虚函数,因此它不显示多态行为。


谢谢。但是除了我试图通过强制转换来解决问题之外,为什么Cell始终需要至少一个虚拟方法才能使用dynamic_cast呢? - tim_a
@tim_a dynamic_cast和虚函数需要将一些信息嵌入对象中,但这会稍微增加其大小,因此C++允许您选择是否添加该信息。 - Neil Kirk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接