通过对信号和槽的引用传递抽象 class 参数

Passing abstract class parameters by references to signals and slots

我想通过引用它们的基数来传递我的对象 class:
connect(pCaller, SIGNAL(sig2(const IBase &)), pReceiver, SLOT(slot2(const IBase &)));

但是我收到 运行-time 错误:

QObject::connect: Cannot queue arguments of type 'IBase' (Make sure 'IBase' is registered using qRegisterMetaType().)

因此我补充:
qRegisterMetaType<IBase>("IBase");

并得到一个 编译时 错误:

error C2259: 'IBase': cannot instantiate abstract class

解决此问题的最佳方法是什么?

  1. 你的 class IBase 必须是可复制和可构造的,如果你想直接传递它(而不是通过指针)
  2. 您需要在 header 中使用 Q_DECLARE_METATYPE 宏注册 IBase *(仅在全局命名空间中)- Q_DECLARE_METATYPE( IBase * )。指针是 POD 类型,所以它们是 copyable/constructable.
  3. 如果要在不同线程之间传递IBase *,需要用qRegisterMetaType<IBase *>()调用注册class;
  4. 通过信号传递指针是不好的做法,因为很难控制传递的指针的生命周期 objects。
  5. 好的解决方法:您可以使用 Q_DECLARE_METATYPE( IBase * ) 宏注册您的类型,并使用 QVariant 包装您的变量:QVariant wrapper; wrapper.setValue( p ); p = wrapper.value<IBase *>();.

您收到此错误是因为调用方和接收方位于不同的线程中。跨线程槽调用需要能够复制所有参数。由于您通过引用传递基类型,因此通常无法复制它:(