我正在Qt中实现低级插件,但偶然发现了一个奇怪的编译错误。
当我尝试使用qobject_cast将插件实例转换为 const 接口指针时,它告诉我接口本身应该继承QObject并使用Q_OBJECT宏。
但是,当我使用qobject_cast强制转换为非常量接口指针时,它可以正常编译。
我有一个界面:
class PluginInterface
{
public:
PluginInterface(const QString &string);
virtual void doSomething() const = 0;
protected:
QString string;
};
Q_DECLARE_INTERFACE(PluginInterface, "PluginInterface")
和一个实现:
class PLUGINSHARED_EXPORT Plugin : public QObject, public PluginInterface
{
Q_OBJECT
Q_INTERFACES(PluginInterface)
Q_PLUGIN_METADATA(IID "Plugin")
public:
Plugin();
void doSomething() const;
};
当尝试使用qobject_cast强制转换为const指针进行编译时,它抱怨PluginInterface应该继承自QObject并使用Q_OBJECT宏。
QPluginLoader loader("C:/Users/Henrique/Documents/Qt Projects/PluginTest/Plugin.dll");
const PluginInterface *interface = qobject_cast<const PluginInterface *>(loader.instance());
interface->doSomething();
但是这可以很好地编译,即强制转换为非常量PluginInterface指针。
QPluginLoader loader("C:/Users/Henrique/Documents/Qt Projects/PluginTest/Plugin.dll");
const PluginInterface *interface = qobject_cast<PluginInterface *>(loader.instance());
interface->doSomething();
为什么会这样?
答案 0 :(得分:1)
我认为这是因为宏Q_DECLARE_INTERFACE
无法实现此功能。
Q_DECLARE_INTERFACE
定义:
# define Q_DECLARE_INTERFACE(IFace, IId) \
template <> inline const char *qobject_interface_iid<IFace *>() \
{ return IId; } \
template <> inline IFace *qobject_cast<IFace *>(QObject *object) \
{ return reinterpret_cast<IFace *>((object ? object->qt_metacast(IId) : nullptr)); } \
template <> inline IFace *qobject_cast<IFace *>(const QObject *object) \
{ return reinterpret_cast<IFace *>((object ? const_cast<QObject *>(object)->qt_metacast(IId) : nullptr)); }
#endif // Q_MOC_RUN
我们可以看到,该宏仅包含以下qobject_cast
个函数:template <> inline IFace *qobject_cast<IFace *>(QObject *object)
和template <> inline IFace *qobject_cast<IFace *>(const QObject *object)
。