7

我派生了 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,Ubuntut 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() );
}

但这似乎不会导致编译错误...

4

2 回答 2

15

从 QObject 继承只是为了强制转换是没有意义的。qobject_cast 相对于动态转换的优势在qobject_cast 文档中得到了很好的总结:

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

如果你有 QObjects 很好,而且很有用,但如果你想从 QObject 继承它,那么它不值得从 QObject 继承。

此外,对于 QGraphicsIems 有qgraphicsitem_cast,它应该完全符合您的要求:)

于 2011-06-21T20:40:31.753 回答
1

您必须将 QObject 指针传递给 qobject_cast() 并且 QGraphicsScene::itemAt 返回一个 QGraphicsItem 指针。正如您所提到的,由于 QGraphicsItem 不是从 QObject 派生的,因此编译器给了您该错误。

于 2011-06-21T20:41:14.653 回答