从接口到Qobject的铸造

casting from interface to QObject

本文关键字:Qobject 接口      更新时间:2023-10-16

我在标题文件中有一个接口类。

class Interface
{
...
}
#define InterfaceIID "Interface"
Q_DECLARE_INTERFACE(Interface, InterfaceIID)

预计将像这样实施

class Implementation : public QWidget, public Interface
{
    Q_OBJECT
    Q_INTERFACES(Interface)
    ...
}

我对实现在应用程序中传递的界面的对象有指示。现在我知道每个接口对象也是QWIDGET,因为这是唯一受支持的用例。

我的问题现在是,当我需要一个Qwidget对象时,如何将接口对象施加到qwidget?

qobject_cast<QWidget*>(interface) //does not compile
dynamic_cast<QWidget*>(interface) //works but is it the right way?

使用dynamic_cast()是唯一的方法?我可以使用qobject_cast()从Qwidget施放到接口,但反向不起作用。

我了解Dynamic_cast()在共享库中不安全,因此我试图避免它。

正确的方法是什么?

第二个是正确的。qObjectCast是将QObject投入"任何东西",而不是相反。那就是动态演员的目的:

QObject *intfObject = pluginLoader.instance();
Interface *intf = qobject_cast<Interface *>(intfObject);//only works if the object has Q_INTERFACES(Interface)
QWidget *intfWidget = dynamic_cast<QWidget*>(intf);

注意:上面的qobject_cast可以很容易地用dynamic_cast替换。但是,如果可能,请务必使用qobject_cast。原因(来自文档):

qobject_cast()函数的行为与标准C dynamic_cast()相似,其优点是它不需要RTTI支持,并且在动态库边界上起作用。

它使用QTS Metasystem(QmetaObject)执行铸件。而且,除此之外,它似乎比dynamic_cast更快。

您无法使用qobject_cast将接口投放到QWidget的原因是接口本身不继承QObject(并且没有Q_OBJECT宏)。因此,它没有metaObject,并且无法使用qobject_cast

编辑:
避免动态铸造的一种方法是始终将插件作为QObject。如果您需要它作为小部件,请用qobject_cast施放它。您的Interface也是如此。只要您以 QObject为例,您将永远不必进行dynamic_cast。

注意:如果您需要知道插件的种类,请为每个接口创建一个小包装类。