尝试使用qobject_cast构造指针时的编译问题

时间:2019-05-11 21:11:49

标签: c++ qt

我正在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();

为什么会这样?

1 个答案:

答案 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)