QT: проблема с qobject_cast - PullRequest
       2

QT: проблема с qobject_cast

7 голосов
/ 22 июня 2011

Я получил классы 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, GCC 4.4.3 в 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*)’

Затем я заметил, что QGraphicsItem не наследует QObject, поэтому я сделал свой производный класс QGraphicsItem множественным наследованием от QObject и QGraphicsItem, и после добавления макроса Q_OBJECT и перестройки проекта я получаю ту же ошибку.

Я поступаю неправильно? Я знаю, что это плохой дизайн, чтобы пытаться приводить родительский класс как дочерний, но в этом случае это похоже на то, что я хочу, так как мой производный класс элементов имеет новую функциональность, и его объектам нужен способ вызывать эту новую функциональность на элементы вокруг себя, и запрос объекта сцены предметов с itemAt () кажется лучшим способом - но мне нужно itemAt (), чтобы вернуть указатель правильного типа. Я могу обойти это, заставив производные элементы приводить QGraphicsItem *, возвращенный QGraphicsScene :: itemAt (), используя dynamic_cast, но я не совсем понимаю, почему это работает, а не qobject_cast, или преимущества или недостатки использования dynamic_cast по сравнению с qobject_cast .

EDIT: забыл упомянуть, что я также переопределил QGraphicsItem :: scene () в своем производном классе, чтобы вернуть DerivedScene *, как

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

но, похоже, это не вызывает ошибку компиляции ...

Ответы [ 2 ]

15 голосов
/ 22 июня 2011

Нет смысла наследовать от QObject только для приведения. Преимущество qobject_cast избыточное динамическое приведение суммируется в значительной степени в документации qobject_cast :

Функция qobject_cast () ведет себя аналогично стандартному C ++ dynamic_cast (), с преимуществами, которые не требуют поддержки RTTI и работают через границы динамической библиотеки.

Приятно иметь и полезно, если у вас есть QObjects, но не стоит наследовать от QObject, если это все, что вы хотите от QObject.

Также для QGraphicsIems есть qgraphicsitem_cast , который должен делать именно то, что вы хотите:)

1 голос
/ 22 июня 2011

Вы должны передать указатель QObject в qobject_cast (), и QGraphicsScene :: itemAt возвращает указатель QGraphicsItem. Поскольку, как вы упомянули, QGraphicsItem не является производным от QObject, компилятор выдал вам эту ошибку.

...