2011-06-21 22 views
7

He derivado las clases QGraphicsItem y QGraphicsScene. Quiero que los elementos puedan llamar a scene() y obtener derviedGraphicsItem * en lugar de QGraphicsItem *, así que reimplementó QGraphicsScene :: itemAt para devolver un puntero derivado.QT: problema con qobject_cast

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

me sale el siguiente error (Qt 4.6, GCC 4.4.3 en Ubuntut 10,4)

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

luego me di QGraphicsItem no hereda QObject, así que hice mi clase derivada QGraphicsItem tener múltiples herencia de QObject y QGraphicsItem, y después de agregar la macro Q_OBJECT y reconstruir el proyecto obtengo el mismo error.

¿Voy por esto de la manera incorrecta? Sé que se supone que es un mal diseño intentar lanzar una clase padre como un niño, pero en este caso parece lo que quiero, ya que mi clase de elemento derivado tiene una nueva funcionalidad y sus objetos necesitan una forma de llamar a esa nueva funcionalidad en elementos alrededor de ellos mismos, y preguntando a los objetos de escena de elementos con itemAt() parece la mejor manera, pero necesito itemAt() para devolver un puntero del tipo correcto. Puedo evitar esto haciendo que los elementos derivados emitan QGraphicsItem * devuelto por QGraphicsScene :: itemAt() usando dynamic_cast, pero realmente no entiendo por qué funciona y no qobject_cast, o los beneficios o desventajas de usar dynamic_cast vs. qobject_cast .

EDIT: olvidó mencionar que también Reimplementado QGraphicsItem :: escena() en mi clase derivada para devolver un DerivedScene *, como

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

pero esto no parece ser la causa de un error de compilación ...

Respuesta

15

No tiene sentido heredar de QObject solo para el casting. La ventaja de qobject_cast más dinámico reparto se resume más o menos en el qobject_cast documentation:

la qobject_cast() función se comporta de manera similar al moldeado dinámico estándar de C++(), con la ventaja de que no requiere el apoyo de RTTI y funciona a través de límites dinámicos de biblioteca.

Es bueno tener y útil si tiene QObjects, pero no vale la pena a heredar de QObject si es todo lo que quieres de QObject.

Además, para QGraphicsIems hay qgraphicsitem_cast, lo que debería hacer exactamente lo que quiere :)

+1

Guau, no puedo creer que haya echado de menos ... solo el tipo reimplementado() para cada elemento gráfico derivado y reemplazado qobject_cast con qgraphicsitem_cast y estamos en el negocio. ¡Gracias! – weevilo

1

Usted tiene que pasar un puntero a QObject qobject_cast() y QGraphicsScene :: itemAt devuelve un puntero QGraphicsItem. Dado que, como mencionó, QGraphicsItem no se deriva de QObject, el compilador le dio ese error.

+0

Veo por qué lo que estaba tratando de hacer es tonto, pero me gustaría entender por qué aún no funciona después de hacer que mis elementos derivados hereden de QObject. ¿Es porque su clase base también debe derivarse de QObject (en este caso, QGraphicsItem)? – weevilo

+0

Obtuvo un error de compilación porque estaba pasando algo del tipo incorrecto a la función. El compilador dijo que no podía encontrar una función que aceptara ese tipo. Aunque su objeto derivado era del tipo correcto, la función no devuelve ese tipo. –