在了解具体子类类型时使用C风格转换进行向下转换

时间:2012-10-04 20:51:34

标签: c++ qt casting downcast

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

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

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

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

如果我将QObject *parent()投射到House*以实施House *house() const,是否可以?

Qt建议使用qobject_cast<House*>(parent()),如果0未从QObject* parent()继承,则返回House,使投射类型安全。但在发布模式下,我想避免这种缓慢的演员表。我描述了一种特殊的算法,它在执行C风格的强制转换而不是qobject_casts时的执行速度提高了三倍。这是因为qobject_cast在运行时向元对象询问类型信息,当经常调用 very 时会导致相当大的减速。

所以我最终得到的是:

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

这将在调试模式下断言父级确实是一个House,而在发布模式下只能高效地进行C风格的转换。

要说明一点:我知道当C ++程序员进行C风格的演员表时,人们会大喊大叫,但在这种情况下它会好吗?

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

1 个答案:

答案 0 :(得分:3)

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