1

在我的项目中,我有一棵不同类型的 QObjects 树。让我给你一个简单的例子,它应该让你明白我在说什么。这可能是一个示例性的 QObject 树(不是继承图,但有点类似于类图),我们从顶部的根对象开始,并在下面列出其子对象:

                                   City
                                     |
                                  Street
                                 /      \
                            House       ...
                           /     \
                       Floor     ...
                       /   \
                   Room    ...

虽然 QObject 树不一定遵循此规则,但在我的情况下,树中的每个类都有一个特定类型的父级。所以,以一个关系为例,一个房子可以有一些楼层和其他类型的孩子,但一个楼层是房子的孩子,只有房子

现在,如果我将它们建模为 QObject 派生类,则应该通过内部查看它的接口来class Floor给我它的接口。我真的知道这个父级将是 type ,因为我将它设计成这样,并且程序员坚持这个设计。House *house()QObject::parent()House*

如果我用 C 风格强制QObject *parent()转换House*来实现可以House *house() const吗?

Qt 建议使用qobject_cast<House*>(parent())0如果QObject* parent()不继承自则返回House,使强制转换类型安全。但在发布模式下,我想避免这种缓慢的演员阵容。我分析了一种特定的算法,它在执行 C 样式转换而不是 qobject_casts 时执行速度快三倍。这是因为 qobject_cast 在运行时向元对象询问类型信息,因此在经常调用时会导致相当大的速度下降。

所以我最终得到的是:

House *Floor::house() const {
    Q_ASSERT(qobject_cast<House*>(parent()));
    return (House*)parent();
}

这将在调试模式下断言父级确实是 House,而在发布模式下仅有效地进行 C 样式转换。

言归正传:我知道当 C++ 程序员进行 C 风格转换时人们会大喊大叫,但在这种情况下可以吗?

另一种解决方案是将特定类型的父指针另外存储为成员变量,但我认为这是多余的,我也喜欢树反映在返回树父的那些方法中。

4

1 回答 1

3

如果您确定所有权图不会更改,即使在维护期间也是如此,那么未经类型检查的强制转换是安全的。您可以使用static_cast<House*>(parent()), 速度很快,或者,如果您真的愿意,可以使用 C 风格的演员表。但是 C 风格的演员并不比 C++ 快static_cast

于 2012-10-04T20:55:42.330 回答