У меня есть класс (MyClass
) это наследовало большую часть его функциональности от спокойного встроенного объекта (QGraphicsTextItem
). QGraphicsTextItem
наследовался косвенно QObject
. MyClass
также реализует интерфейс, MyInterface
.
class MyClass : public QGraphicsTextItem, public MyInterface
Я должен смочь использовать connect
и disconnect
на MyInterface*
. Но это появляется это connect
и disconnect
только продолжите работать QObject*
экземпляры. Так как QT не поддерживает множественное наследование от QObject-производных-классов, я не могу произойти MyInterface
от QObject
. (И при этом это не имело бы большого смысла для интерфейса так или иначе.)
Существует обсуждение проблемы онлайн, но IMO, предлагаемое решение довольно бесполезно в общем падеже (получающий доступ к объекту через его интерфейс), потому что Вы не можете соединить сигналы и слоты от MyInterface*
но должен бросить его к производному типу. С тех пор MyClass
один из многих MyInterface
- производные классы, это требовало бы "вонючих кодом" if-this-cast-to-this-else-if-that-cast-to-that операторов и побеждает цель интерфейса.
Существует ли хорошее решение этого ограничения?
ОБНОВЛЕНИЕ: Я заметил что если я dynamic_cast
a MyInterface*
кому: QObject*
(потому что я знаю все MyInterface
- производные классы также наследовались в конечном счете QObject
, это, кажется, работает. Это:
MyInterface *my_interface_instance = GetInstance();
connect(dynamic_cast(my_interface_instance), SIGNAL(MyInterfaceSignal()), this, SLOT(TempSlot()));
Но это действительно кажется, что я прошу неопределенное поведение....
Вы сами нашли ответ: dynamic_cast работает, как и следовало ожидать. Это не неопределенное поведение. Если экземпляр MyInterface, который вы получили, не является QObject, приведение вернет null, и вы можете защитить себя от этого (чего не произойдет, поскольку вы сказали, что все экземпляры интерфейса также являются QObject). Однако помните, что для работы вам необходимо включить RTTI.
Я бы также предложил несколько других предложений:
Используйте функцию Q_INTERFACES (она не только для плагинов). Тогда вы будете работать с QObject и запросить MyInterface, используя qobject_cast, когда это действительно необходимо. Я не знаю подробно вашу проблему, но поскольку вы знаете, что все экземпляры MyInterface также являются объектами QObject, это кажется наиболее разумным подходом.
Добавить абстрактный метод QObject * asQObject ()
в MyInterface и реализовать его как {вернуть это; }
во всех подклассах.
Наличие QGraphicsTextItem (композиция) вместо , являющегося одним (наследование).
Вы можете объявить MyInterface, который принимает QObject в своем конструкторе:
class MyInterface {
public:
MyInterface(QObject * object);
QObject * object() { return m_object; }
...
private:
QObject * m_object;
};
MyInterface::MyInterface(QObject * object) :
m_object(object)
{
...
}
Затем в конструкторе MyClass:
MyClass::MyClass() :
MyInterface(this)
{
...
}
И вы можете подключить сигнал:
MyInterface *my_interface_instance = GetInstance();
connect(my_interface_instance->object(), SIGNAL(MyInterfaceSignal()), this, SLOT(TempSlot()));