Используя спокойные сигналы и слоты со множественным наследованием

У меня есть класс (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()));

Но это действительно кажется, что я прошу неопределенное поведение....

9
задан Louis Langholtz 14 April 2018 в 13:59
поделиться

2 ответа

Вы сами нашли ответ: dynamic_cast работает, как и следовало ожидать. Это не неопределенное поведение. Если экземпляр MyInterface, который вы получили, не является QObject, приведение вернет null, и вы можете защитить себя от этого (чего не произойдет, поскольку вы сказали, что все экземпляры интерфейса также являются QObject). Однако помните, что для работы вам необходимо включить RTTI.

Я бы также предложил несколько других предложений:

  • Используйте функцию Q_INTERFACES (она не только для плагинов). Тогда вы будете работать с QObject и запросить MyInterface, используя qobject_cast, когда это действительно необходимо. Я не знаю подробно вашу проблему, но поскольку вы знаете, что все экземпляры MyInterface также являются объектами QObject, это кажется наиболее разумным подходом.

  • Добавить абстрактный метод QObject * asQObject () в MyInterface и реализовать его как {вернуть это; } во всех подклассах.

  • Наличие QGraphicsTextItem (композиция) вместо , являющегося одним (наследование).

12
ответ дан 4 December 2019 в 11:03
поделиться

Вы можете объявить 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()));
7
ответ дан 4 December 2019 в 11:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: