在我的项目中,我有一个不同类型的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风格的演员表时,人们会大喊大叫,但在这种情况下它会好吗?
另一种解决方案是将特定类型的父指针另外存储为成员变量,但我认为这是多余的,我也喜欢树反映在返回树父类的那些方法中。
答案 0 :(得分:3)
如果您确定所有权图表不会更改,即使在维护期间也是如此,那么未经过类型检查的演员表是安全的。您可以使用static_cast<House*>(parent())
,这很快,或者,如果您真的想要,可以使用C风格的演员表。但C风格的演员表并不比C ++ static_cast
快。