2011-06-21 17 views
7

私はQGraphicsItemクラスとQGraphicsSceneクラスを派生させました。アイテムをscene()を呼び出してQGraphicsItem *の代わりにderviedGraphicsItem *を取得できるようにするため、QGraphicsScene :: itemAtを再実装して派生ポインタを返すようにします。QT:qobject_castの問題

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

は、私はその後、QObjectを継承しませんQGraphicsItem気づい

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*)’ 

(Ubuntut 10.4上のQt 4.6、GCC 4.4.3を)次のエラーを取得するので、私は私の派生QGraphicsItemクラスが複数持って作られましたQObjectとQGraphicsItemから継承し、Q_OBJECTマクロを追加してプロジェクトを再構築した後も同じエラーが発生します。

私はこれについて間違った方法をしていますか?親クラスを子としてキャストしようとするとデザインが悪いはずですが、この場合は、派生したアイテムクラスに新しい機能があり、そのオブジェクトに新しい機能を呼び出す方法が必要なので、 itemAt()を使ってアイテムシーンオブジェクトに質問するのが最善の方法だと思われますが、正しいタイプのポインタを返すにはitemAt()が必要です。私はこれを回避するために、QGraphicsItem *をQGraphicsScene :: itemAt()がdynamic_castを使用して返したものをキャストすることでこの問題を回避することができますが、なぜ動作してqobject_castでないのか、またはdynamic_castとqobject_castを使用するメリットまたはデメリット。

EDIT: は

DerivedScene* DerivedItem::scene() const 
{ 
    return qobject_cast< DerivedScene * >(QGraphicsItem::scene()); 
} 

として、DerivedScene *を返すために、私の派生クラスでのシーン()::私もQGraphicsItemを再実装することを言及するのを忘れてしまったが、これはコンパイルエラーを引き起こしていると思われません...

答えて

15

キャストのためだけにQObjectから継承することに意味はありません。動的キャストを超えるqobject_cast の利点がqobject_cast documentationでほとんどをまとめている:

qobject_cast()関数は、RTTIのサポートを必要としないという利点と、)(標準C++のdynamic_castと同じように動作し、ダイナミックライブラリの境界を越えて動作します。

QObjectを持っていると便利ですが、QObjectから必要なものがあればそれを継承する価値はありません。

また、QGraphicsIemsのためにあなたは:)

+1

私はそれを逃したとは思えません...それぞれの派生グラフィックスアイテムに対してtype()を再実装し、qgjecticscast に置き換えました。ありがとう! – weevilo

1

は、あなたが(qobject_castするQObjectのポインタを渡す必要がし​​たい正確に何をすべきqgraphicsitem_castが、)があるとQGraphicsScene :: QGraphicsItemポインタを返すitemAt。あなたが言ったように、QGraphicsItemはQObjectから派生していないので、コンパイラはあなたにそのエラーを与えました。

+0

私は何をしようとしていたのか愚かなのですが、QObjectから派生したアイテムを継承してもまだそれがうまくいかなかった理由を理解したいと思います。なぜなら、それらの基底クラスはQObject(この場合はQGraphicsItem)から派生しなければならないからです。 – weevilo

+0

関数に間違った型のものを渡していたため、コンパイルエラーが発生しました。コンパイラは、その型を受け入れる関数を見つけることができないと言いました。派生したオブジェクトが正しい型であっても、関数はその型を返しません。 –

関連する問題