QT:qobject_cast出现问题

7

我已经派生了QGraphicsItem和QGraphicsScene类。我希望项目能够调用scene()方法并获取derivedGraphicsItem *而不是QGraphicsItem *,因此我重新实现了QGraphicsScene::itemAt以返回一个派生指针。

DerivedItem* DerivedScene::itemAt( const QPointF &position, const QTransform &dt ) const
{
    return qobject_cast< DerivedItem * >(
            QGraphicsScene::itemAt(position, dt) );
}

我在Ubuntu 10.4上使用Qt 4.6和GCC 4.4.3时遇到了以下错误:
scene.cpp: In member function ‘DerivedItem* DerivedScene::itemAt(qreal, qreal, const QTransform&) const’:
scene.cpp:28: error: no matching function for call to ‘qobject_cast(QGraphicsItem*)’

我注意到QGraphicsItem没有继承QObject,所以我让我的派生QGraphicsItem类从QObject和QGraphicsItem多重继承,并在添加了Q_OBJECT宏并重新构建项目后,我得到了相同的错误。
我这样做是错的吗?我知道试图将父类强制转换为子类是不好的设计,但在这种情况下似乎是我想要的,因为我的派生项类具有新功能,其对象需要一种调用周围项上的新功能的方法,并且使用itemAt()询问项场景对象似乎是最好的方法 - 但我需要itemAt()返回正确类型的指针。我可以通过让派生项使用dynamic_cast将QGraphicsScene :: itemAt()返回的QGraphicsItem *进行强制转换来解决此问题,但我真的不理解为什么dynamic_cast可以而qobject_cast不行,或者使用dynamic_cast与qobject_cast的优缺点。
编辑:我忘记提及我还在我的派生类中重新实现了QGraphicsItem :: scene()以返回DerivedScene *。
DerivedScene* DerivedItem::scene() const
{
    return qobject_cast< DerivedScene * >( QGraphicsItem::scene() );
}

但是这似乎并没有引起编译错误...

2个回答

15
仅为了类型转换而从QObject继承是没有意义的。 qobject_cast比dynamic_cast的优点在于其文档中已经总结得很清楚:qobject_cast文档

  

qobject_cast()函数的行为类似于标准的C ++ dynamic_cast(),其优点是不需要RTTI支持并且可以跨动态库边界工作。

如果仅想要使用QObject的类型转换功能,则从QObject继承并没有多大价值,虽然它对于拥有QObjects的项目非常好用。

此外,对于QGraphicsIems,还有qgraphicsitem_cast函数,它应该可以完美地满足您的需求:)


1
哇,真不敢相信我错过了那个...只是为每个派生图形项重新实现了 type(),并用 qgraphicsitem_cast<DerivedItem *> 替换了 qobject_cast<DerivedItem *>,我们的业务现在正常运行。谢谢! - weevilo

1
你需要向 qobject_cast() 函数传递一个 QObject 指针,而 QGraphicsScene::itemAt 返回的是 QGraphicsItem 指针。正如你所提到的,由于 QGraphicsItem 并不从 QObject 派生而来,因此编译器会给出错误提示。

我明白我尝试做的事情为什么很愚蠢,但我想知道在我的派生项继承自QObject之后为什么仍然无法正常工作。是因为它们的基类也必须从QObject派生(在本例中为QGraphicsItem)吗? - weevilo
你之前遇到编译器错误是因为你向函数传递了错误类型的参数。编译器提示找不到接受该类型参数的函数。即使你的派生对象类型正确,但该函数并不返回该类型。 - Dusty Campbell

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