7

QGraphicsItem および QGraphicsScene クラスを派生させました。アイテムが Scene() を呼び出して、QGraphicsItem * の代わりに derviedGraphicsItem * を取得できるようにしたいので、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() が必要です。QGraphicsScene::itemAt() によって返された QGraphicsItem * を dynamic_cast を使用して派生アイテムにキャストさせることで、これを回避できますが、なぜそれが機能し、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サポートを必要とせず、ダイナミックライブラリの境界を越えて機能するという利点があります。

QObjectがある場合は便利ですが、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 に答える