Russian Qt Forum

Qt => Общие вопросы => Тема начата: frostyland от Октябрь 14, 2010, 11:33



Название: Как правильно реализовывать иерархию интерфейсов
Отправлено: frostyland от Октябрь 14, 2010, 11:33
Здравствуйте.
У меня есть иерархия

Код
C++ (Qt)
class IInterface <- class ISubInterface
 

и, соответственно, реализатор

Код
C++ (Qt)
class Realize : public ISubInterface
 

При классической RTTI объект Realize должен корректно приводиться как к одному, так и к другому интерфейсу
Код
C++ (Qt)
Realize* r = new Realize;
ISubInterface* si = dynamic_cast<ISubInterface>(r) // ok
IInterface* si = dynamic_cast<IInterface>(r) // ok
 

Нативная реализация Qt предполагает использование макроса
Код
C++ (Qt)
Q_INTERFACES(ISubInterface)
в классе-реализаторе.
Но в этом случае приведение работает только к указанному классу
Код
C++ (Qt)
ISubInterface* si = qobject_cast<ISubInterface>(r) // ok
IInterface* si = qobject_cast<IInterface>(r) // false

Я пдосмотрел семплы и сделал подобно множественному наследованию, указав весь граф базовых интерфейсов
Код
C++ (Qt)
Q_INTERFACES(Vcon::IGenericPlugin Vcon::IGraphicPlugin)

Приведение типов стало работать.
Код
C++ (Qt)
ISubInterface* si = qobject_cast<ISubInterface>(r) // ok
IInterface* si = qobject_cast<IInterface>(r) // ok

Так как в ассистенте и сети я не нашел ничего, вопрос к гуру: это кошерное решение?


Название: Re: Как правильно реализовывать иерархию интерфейсов
Отправлено: Vass от Октябрь 14, 2010, 13:18
как то странно Вы приводите тип, Вы * забыли в обоих случаях.
Код:
ISubInterface* si = dynamic_cast<ISubInterface *>(r) // ok
IInterface* si = dynamic_cast<IInterface *>(r) // ok

Решение через qobject_cast в рамках Qt хорошо, но нужно помнить, что оно работает только для наследников QObject.


Название: Re: Как правильно реализовывать иерархию интерфейсов
Отправлено: frostyland от Октябрь 14, 2010, 13:29
как то странно Вы приводите тип, Вы * забыли в обоих случаях.
Код:
ISubInterface* si = dynamic_cast<ISubInterface *>(r) // ok
IInterface* si = dynamic_cast<IInterface *>(r) // ok

Решение через qobject_cast в рамках Qt хорошо, но нужно помнить, что оно работает только для наследников QObject.

Да-да это я псевдокодил, конечно все с *.
Про QObject помню, а по другому сложно с интерфейсами. Как без qobject_cast разбираться с типами? Я против полей типа, как трудно расширяемого решения.


Название: Re: Как правильно реализовывать иерархию интерфейсов
Отправлено: ufna от Октябрь 14, 2010, 14:54
О, тут с этим наигрался вдоволь недавно :)

Когда делаешь кутэшные интерфейсы:
а) они не должны быть унаследованы от QObject, макросов Q_OBJECT тоже не нужно, потому как QDeclareInterface(..) кутэшные свойства QObject'ов добавляет "внутри"
б) приведение к "старшим в иерархии" интерфейсам отлично работает через dynamic_cast (но к прямому "родителю" через qobject), либо Q_INTERFACES(..) указываешь еще и остальные нужные и тогда qobject_cast, но это уже излишне (а, ну это ты и сделал). Оба варианта кошерны.