我已经派生了QGraphicsItem和QGraphicsScene类。我希望这些项能够调用scene()并获取一个derviedGraphicsItem *而不是QGraphicsItem *,所以我重新实现了QGraphicsScene :: itemAt以返回一个派生指针。
DerivedItem* DerivedScene::itemAt( const QPointF &position, const QTransform &dt ) const
{
return qobject_cast< DerivedItem * >(
QGraphicsScene::itemAt(position, dt) );
}
我收到以下错误(Qt 4.6,UCCntut 10.4上的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 *来解决这个问题,但我真的不明白为什么这样做而不是qobject_cast,或者使用dynamic_cast与qobject_cast的好处或缺点
编辑: 忘了提到我还在我的派生类中重新实现了QGraphicsItem :: scene()以返回DerivedScene *,如
DerivedScene* DerivedItem::scene() const
{
return qobject_cast< DerivedScene * >( QGraphicsItem::scene() );
}
但这似乎没有导致编译错误......
答案 0 :(得分:15)
仅仅为了强制转换从QObject继承是没有意义的。 qobject_cast的优点 动态演员在qobject_cast documentation:
中总结得很多qobject_cast()函数的行为类似于标准C ++ dynamic_cast(),其优点是它不需要RTTI支持,并且它可以跨动态库边界工作。
如果你有QObjects,那么拥有和有用是很好的,但是如果你想从QObject中获取它,则不值得从QObject继承。
此外,对于QGraphicsIems,有qgraphicsitem_cast,它应该完全符合您的要求:)
答案 1 :(得分:1)
您必须将QObject指针传递给qobject_cast(),QGraphicsScene :: itemAt返回一个QGraphicsItem指针。因为,如你所提到的,QGraphicsItem不是从QObject派生的,编译器给你的错误。