【发布时间】:2010-07-13 16:56:37
【问题描述】:
我有一系列代表“智能”地图元素的类:MapTextElement、MapIconElement 等。这些类扩展了各种 Qt 图形项类,但也提供了通用功能,例如返回的抽象工厂方法专门针对每个类的属性面板。我已经在一个纯虚类MapElementInterface 中声明了这些常用方法。然后我的类乘以继承适当的 Qt 基类以及接口:
class MapTextElement : public QGraphicsTextItem, public MapElementInterface
class MapIconElement : public QGraphicsItem, public MapElementInterface
所以我的类层次结构看起来有点像:
+-------------+ +-------------------+
|QGraphicsItem| |MapElementInterface|
+-------------+ +-------------------+
^ ^ ^
| | |
+------+------+ | |
| | | |
+-----------------+ +--------------+ |
|QGraphicsTextItem| |MapIconElement| |
+-----------------+ +--------------+ |
^ |
| |
+-------------------+ +-----+
| |
+--------------+
|MapTextElement|
+--------------+
我从 Qt 提供的方法接收到一个指向 QGraphicsItem 的指针。在这种情况下,我知道指针不仅是QGraphicsItem,还有MapElementInterface。我想将指针视为MapElementInterface。
QList<QGraphicsItem*> selected = scene_->selectedItems();
if (selected.count() == 1) {
// We know that the selected item implements MapEditorInterface
MapElementInterface *element = SOME_CAST_HERE<MapElementInterface*>(selected[0]);
QWidget *panel = element->GeneratePropertyPanel(property_dock_);
}
正确的演员阵容是什么?还是我完全走错了路?
【问题讨论】:
-
您不能在类层次结构中水平投射,因为 QGraphicsItem 和 MapElementInterface 不相关。您必须向上转换为派生类型,然后再向下转换(使用 dynamic_cast)
-
@Martin:它确实似乎使用直接dynamic_cast工作。您能否向我指出一篇在线文章,该文章更详细地解释了您预期的问题或“陷阱”?谢谢!
-
当我尝试在两种不相关的“QGraphicsItem 和 MapElementInterface”类型之间进行动态转换时,它返回一个 NULL 指针。因此,您必须在做其他事情,否则两者之间存在某种关系。您只能通过将 (dynamic_cast) 向上转换然后向下转换来从一个转换到另一个。如果您使用的是另一个演员表 (rinterpret_cast),那么您处于未定义的领域。
-
@Martin:您能告诉我您使用的是什么编译器/运行时吗?也许我们看到的行为会因环境而异。很高兴知道。此外,您正在尝试从 pointer 到 multiply-inherited 对象的 dynamic_cast,就像我的示例一样,对吧?
-
gcc(3.? 和 4.2)和开发工作室 10。但这就是 dynamic_cast 应该做的。如果类型之间没有关系(如上所述),则它必须返回 NULL。因此,您要么使用不同的演员表(这是错误的),要么您未提及的类型之间存在另一种关系,或者您正在上下树进行多次演员表。
标签: c++ casting multiple-inheritance