繁体   English   中英

如何为 QObject class 创建接口

[英]How create Interface for QObject class

我想用信号/槽系统为QObject class 创建一个接口。

下面的代码有效但有一个缺点:接口继承QObject并且没有Q_OBJECT宏。

我想制作一个纯虚拟接口,所以InterfaceClass不应该有构造函数。 但是在RealisationClass中,我无法调用QObject (错误:类型“QObject”不是“RealisationClass”的直接基础)或InterfaceClass (它没有构造函数InterfaceClass(QObject* parent) )构造函数。 此外,我无法在InterfaceClass中添加Q_OBJECT宏(错误:未定义对 InterfaceClass 的“vtable”的引用)

那么,我应该如何更改类以在RealisationClass中添加QObject()构造函数并将Q_OBJECT宏(或删除QObject继承)添加到 InterfaceClass。

接口类.h:

#ifndef INTERFACE_CLASS_H
#define INTERFACE_CLASS_H
#include <QObject>

class InterfaceClass : public QObject {
    Q_OBJECT
 public:
  virtual ~InterfaceClass(){};
  virtual void foo() = 0;
};
Q_DECLARE_INTERFACE(InterfaceClass, "Interface")
#endif // INTERFACE_CLASS_H

实现类.h:

#include <QObject>
#include <QDebug>

#include "InterfaceClass.h"

class RealisationClass : public InterfaceClass {
  Q_OBJECT
  Q_INTERFACES(InterfaceClass)
 public:
    explicit RealisationClass(QObject* parent = nullptr){};
    void foo() override {qDebug() << "Hello, world";};
};

主.cpp:

#include <QCoreApplication>

#include "RealisationClass.h"
#include "InterfaceClass.h"
#include <QObject>
#include <QTimer>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QTimer everySecondTimer;
    everySecondTimer.setInterval(1000);
    QScopedPointer<InterfaceClass> interfacePointer(new RealisationClass);
    QObject::connect(&everySecondTimer, &QTimer::timeout, interfacePointer.get(), &InterfaceClass::foo);
    everySecondTimer.start();
    return a.exec();
}

编辑

Q_OBJECT 宏问题还有另一个原因:我没有将 InterfaceClass.h 作为目标添加到 Cmake 的 AUTOMOC(qmake (moc) 没有处理这个文件)。

使用具有QObject层次结构的接口是一个真正的痛苦。 您通常希望您的接口具有QObject的某些功能(即信号/槽、销毁信号、与 Qt API 集成),但它是一个轻量级的接口定义。 除非重构IQObject以便存在在整个 Qt 代码库中使用的 IQObject,否则您无法获得完美的解决方案。 我推荐的是简单地将所有构造函数调用转发给QObject

#ifndef INTERFACE_CLASS_H
#define INTERFACE_CLASS_H
#include <QObject>

class InterfaceClass : public QObject {
    Q_OBJECT
 public:
  using QObject::QObject; // <<--------

  virtual ~InterfaceClass(){};
  virtual void foo() = 0;
};
Q_DECLARE_INTERFACE(InterfaceClass, "Interface")
#endif // INTERFACE_CLASS_H

通过using QObject::QObject行, InterfaceClass现在具有与QObject具有相同声明的构造函数。 他们所做的就是将调用转发给QObject 有了它,您现在可以在RealisationClass中执行此操作:

#include <QObject>
#include <QDebug>

#include "InterfaceClass.h"

class RealisationClass : public InterfaceClass {
  Q_OBJECT
  Q_INTERFACES(InterfaceClass)
 public:
    explicit RealisationClass(QObject* parent = nullptr)
      : InterfaceClass(parent) // <<------
    {};
    void foo() override {qDebug() << "Hello, world";};
};

这有两个主要缺点:

  1. 由于构造函数,您的界面不再是真正的界面。
  2. 您的派生类不能从以这种方式设计的多个接口继承(菱形继承)。

我仍然需要尝试使用虚拟 inheritance ( class InterfaceClass: public virtual QObject ) 看看是否可以在不引入其他问题的情况下解决#2。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM