Безопасно ли использовать *виртуальное* множественное наследование, если QObject наследуется НАПРЯМУЮ?

Я понимаю, что в целом множественное наследование от QObject производных классов (даже виртуальное множественное наследование) не поддерживается в Qt.

Я понимаю, что причина в том (я думаю), что даже в случае виртуального наследования классы Qt сами виртуально не наследуются от QObject. Например, если вы попытаетесь виртуально вывести класс как из QWidget, так и из QThread, это поместит виртуальное наследование в нерелевантное место в цепочке наследования, и вы все равно получите два экземпляра QObject.

Поэтому я считаю безопасным и поддерживаемым в Qt использование виртуального наследования, когда ЕДИНСТВЕННЫЙ класс Qt, производный от которого является самим QObject.

У меня есть:

class Top : public QObject {};

class Left : public virtual Top {};

class Right : public virtual Top {};

class Bottom : public Left, public Right {}; // Is this safe, and supported by Qt?

Обратите внимание, что экземпляры Bottom действительно имеют только один экземпляр Top (и, следовательно, только один экземпляр QObject), так что кажется, что обоснование отказа от множественного наследования в Qt (даже виртуального множественного наследования) не применимо. здесь.

Тем не менее приведенная выше конструкция приводит к предупреждению компилятора Qt Class Bottom inherits from two QObject subclasses Left and Right. This is not supported!.

Я прав? Безопасно ли игнорировать предупреждение компилятора Qt в этом конкретном сценарии? Является ли приведенная выше конструкция, включающая виртуальное множественное наследование непосредственно от QObject, безопасной и поддерживается в Qt?


person Dan Nissenbaum    schedule 08.05.2013    source источник
comment
Как Qt на самом деле использует этот класс? Если вы просто передаете указатель или ссылку на QObject, то все в порядке. Если он где-то попытается получить смещение члена вместо использования указателя на член, это может быть не так.   -  person Useless    schedule 08.05.2013
comment
@Useless Я надеюсь, что смогу связать сигналы и слоты Qt для Top, Left, Right и/или Bottom.   -  person Dan Nissenbaum    schedule 08.05.2013
comment
Итак, работает это или нет, зависит от деталей того, как они реализованы. Я понятия не имею, каков ответ в таком случае, но, по крайней мере, это ясно для следующего эксперта по Qt...   -  person Useless    schedule 08.05.2013
comment
@Dan: Вы сможете связать сигналы и слоты только для Top. И Top может использовать виртуальные функции для делегирования реализации своим подклассам, но Qt не будет знать, как с ними обращаться.   -  person Ben Voigt    schedule 08.05.2013


Ответы (1)


Нет, Qt никоим образом не поддерживает множественное наследование от QObject.

Проблема не в виртуальном наследовании, а в системе метаобъектов Qt. Каждый базовый класс QObject имеет связанный QMetaObject, который управляет сигналами, слотами, свойствами и т. д., и каждый метаобъект знает своего родителя QObject, поэтому, например. сигналы, которые существуют в родительских классах, могут быть обработаны. Qt moc не может иметь дело с множественным наследованием от QObject или любого из его подклассов.

person Dan Milburn    schedule 08.05.2013
comment
В самом деле, даже определение signal для класса Right (и, предположительно, Left тоже самое) приводит к ошибке компилятора в следующей строке, созданной moc: Right *_t = static_cast<Right *>(_o); with _o a QObject. Так что эта конструкция не только не поддерживается Qt, но и не компилируется. - person Dan Nissenbaum; 08.05.2013
comment
Интересно, есть ли он в списке для Qt, чтобы когда-нибудь поддерживать множественное наследование классов, производных от QObject. - person Dan Nissenbaum; 08.05.2013