Dav*_*eer 9 c++ qt multiple-inheritance qt-signals
我有一个class(MyClass)从Qt内置对象(QGraphicsTextItem)继承其大部分功能.QGraphicsTextItem从中间接继承QObject.MyClass还实现了一个接口MyInterface.
class MyClass : public QGraphicsTextItem, public MyInterface
Run Code Online (Sandbox Code Playgroud)
我需要能够使用connect和disconnect开启MyInterface*.但现在看来,connect并disconnect只在工作QObject*实例.由于Qt不支持从QObject的派生类多继承,我不能得到MyInterface从QObject.(无论如何,这对于界面也没有多大意义.)
有一个问题的讨论在网上,但IMO所提出的解决方案是在通常情况下(访问通过其接口的对象)相当无用的,因为你无法连接的信号和槽MyInterface*,但必须将它转换为派生类型.由于MyClass是许多MyInterface衍生类中的一个,这将需要"代码 - 臭"如果 - 这个 - 演绎 - 否则 - 如果 - 那个 - 演绎到那个语句并且破坏了接口的目的.
这个限制有一个很好的解决方案吗?
更新:我注意到,如果我dynamic_cast一MyInterface*到QObject*(因为我知道所有MyInterface的派生类也最终从继承QObject,它似乎工作即:
MyInterface *my_interface_instance = GetInstance();
connect(dynamic_cast<QObject*>(my_interface_instance), SIGNAL(MyInterfaceSignal()), this, SLOT(TempSlot()));
Run Code Online (Sandbox Code Playgroud)
但是,这真的好像我要求的未定义行为....
and*_*ref 12
您自己找到了答案:dynamic_cast正如您所期望的那样工作.它不是未定义的行为.如果您获得的MyInterface实例不是QObject,则转换将返回null并且您可以保护自己(这不会发生,因为您说接口的所有实例也是QObjects).但请记住,您需要打开RTTI才能使其正常工作.
我还会提出一些其他建议:
使用Q_INTERFACES功能(它不仅适用于插件).然后,当真正需要时,您将使用QObject并使用qobject_cast查询MyInterface.我不太详细地了解你的问题,但是因为你知道所有的MyInterface实例都是QObjects,所以这似乎是最明智的方法.
QObject* asQObject()向MyInterface 添加一个抽象方法,并{ return this; }在所有子类中实现它.
具有一个QGraphicsTextItem(组合物),而不是作为一个(继承).
您可以声明在其构造函数中包含QObject的MyInterface:
class MyInterface {
public:
MyInterface(QObject * object);
QObject * object() { return m_object; }
...
private:
QObject * m_object;
};
MyInterface::MyInterface(QObject * object) :
m_object(object)
{
...
}
Run Code Online (Sandbox Code Playgroud)
然后在MyClass构造函数中:
MyClass::MyClass() :
MyInterface(this)
{
...
}
Run Code Online (Sandbox Code Playgroud)
你可以连接信号:
MyInterface *my_interface_instance = GetInstance();
connect(my_interface_instance->object(), SIGNAL(MyInterfaceSignal()), this, SLOT(TempSlot()));
Run Code Online (Sandbox Code Playgroud)