从接口转换为 QObject
casting from interface to QObject
我在这样的头文件中有一个接口 class。
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 转换为 "anything",而不是相反。这就是动态转换的用途:
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
。原因(来自documentation):
The qobject_cast() function behaves similarly to the standard C++ dynamic_cast(), with the advantages that it doesn't require RTTI support and it works across dynamic library boundaries.
它使用 Qts 元系统 (QMetaObject) 来执行转换。而且,除此之外,它似乎比 dynamic_cast
.
快得多
你不能使用 qobject_cast 将接口转换为 QWidget
的原因是接口本身不继承 QObject(并且没有 Q_OBJECT
宏).因此,它没有元对象,无法使用 qobject_cast
。
编辑:
避免动态转换的一种方法是始终将插件保持为 QObject
。如果你需要它作为小部件,用 qobject_cast
投射它。您的 Interface
也是如此。只要您 store/pass 围绕实例 QObject
,您将永远不必 dynamic_cast.
注意:如果您需要了解插件的种类,请为每个接口创建一个小包装器类。
我在这样的头文件中有一个接口 class。
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 转换为 "anything",而不是相反。这就是动态转换的用途:
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
。原因(来自documentation):
The qobject_cast() function behaves similarly to the standard C++ dynamic_cast(), with the advantages that it doesn't require RTTI support and it works across dynamic library boundaries.
它使用 Qts 元系统 (QMetaObject) 来执行转换。而且,除此之外,它似乎比 dynamic_cast
.
你不能使用 qobject_cast 将接口转换为 QWidget
的原因是接口本身不继承 QObject(并且没有 Q_OBJECT
宏).因此,它没有元对象,无法使用 qobject_cast
。
编辑:
避免动态转换的一种方法是始终将插件保持为 QObject
。如果你需要它作为小部件,用 qobject_cast
投射它。您的 Interface
也是如此。只要您 store/pass 围绕实例 QObject
,您将永远不必 dynamic_cast.
注意:如果您需要了解插件的种类,请为每个接口创建一个小包装器类。