Qt 如何为QObject类创建接口

Qt 如何为QObject类创建接口,qt,qt5,Qt,Qt5,我想为带有信号/插槽系统的QObject类创建一个接口 下面的代码可以工作,但有一个缺点:接口继承QObject,并且没有Q\u对象宏 我想创建一个纯虚拟接口,所以InterfaceClass不应该有构造函数。但是在RealizationClass中,我无法调用QObject(错误:类型'QObject'不是'RealizationClass'的直接基)或InterfaceClass(它没有构造函数InterfaceClass(QObject*parent))构造函数。此外,我无法在Interf

我想为带有信号/插槽系统的
QObject
类创建一个接口

下面的代码可以工作,但有一个缺点:接口继承
QObject
,并且没有
Q\u对象

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

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

INTEFACESCLASS.h:

\ifndef接口\u类\u H
#定义接口类
#包括
类接口类:公共QObject{
Q_对象
公众:
虚拟~InterfaceClass(){};
虚拟void foo()=0;
};
Q_声明_接口(接口类,“接口”)
#endif//INTERFACE\u CLASS\u H
实现类h:

#包括
#包括
#包括“InterfaceClass.h”
类实现类:公共接口类{
Q_对象
Q_接口(接口类)
公众:
显式实现类(QObject*parent=nullptr){};

void foo()覆盖{qDebug()使用具有
QObject
层次结构的接口是一个真正的难题。您经常希望您的接口具有
QObject
的一些功能(即信号/插槽、破坏的信号、与Qt API集成)但它必须是一个轻量级的接口定义。除非对Qt进行重构,以便在整个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
这有两个主要缺点:

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

  • 我仍然需要处理虚拟继承(
    class-InterfaceClass:public-virtual-QObject
    )看看这是否可以在不引入其他问题的情况下解决#2。

    您使用的是哪个版本的qt?适用于Qt5.15和Qt5.9。请在构建之前尝试运行
    qmake
    。此外,您不需要在
    realizationClass
    @Alloces中使用Q#u对象宏是的,这是工作代码(我正在使用Qt5.12.9)。但我无法从RealizationClass调用QObject(父)构造函数。这让我担心。关于Q_OBJECT:“我们强烈建议在QObject的所有子类中使用此宏,无论它们是否实际使用信号、插槽和属性,因为如果不这样做,可能会导致某些函数表现出奇怪的行为。”从这里开始:是的,我知道您需要调用QObject(父)构造函数。这是一种奇怪的行为-我可以使用
    auto*r=new-realizationclass(myQObject)创建您的
    realizationclass
    没有任何问题。关于Q_对象-当您从QObject类继承时,建议您这样做,但您从QObject继承器类继承。对于这种情况,我认为最合适的解决方案不是从QObject继承
    InterfaceClass
    InterfaceClass
    是否需要是
    QObject
    ?如果
    RealizationClass
    使用多重继承从
    InterfaceClass
    QObject
    派生,该怎么办?我想是的,因为我想有可能将“QScopedPointer interfacePointer(新的RealizationClass);”更改为“QScopedPointer interfacePointer(新的InterfaceClass的另一个实现)“和连接将仍然有效,因为我知道使用接口有一个普遍的优势。我创建了像@Dean Johnson说的类。但是信号仍然存在一些问题。我认为最好的方法是创建关于它的新问题。你解决了接口中的信号问题吗?据我所知,没有办法创建虚拟的()。因此,如果向接口添加信号,则无法在RealizationClass声明中添加它。在我的示例中,我在InterfaceClass和ReleaseClass中创建了非虚拟信号。有两个不同的信号-这会导致错误。为了避免错误,我将ReleaseClass信号连接到ReleaseClass构造函数中的InterfaceClass信号。不要将它们设置为虚拟-j必须将信号直接放在接口中。因为信号是由
    moc
    生成的,所以您不需要定义它。而且,永远不会有任何理由像通常在接口中使用虚拟方法那样覆盖信号。有了接口中的信号,您不必将信号的任何内容放在接口中d班。
    #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";};
    };