繁体   English   中英

如何使Qt Signal按值发出而没有编译错误而不是引用?

[英]How to make Qt Signal emit by value without compile errors instead of reference?

我读到qt中的信号/插槽概念应始终通过值而不是引用传递参数,以确保信号/插槽在线程之间完美地工作。

我现在有一段代码,仅当信号的参数是通过引用而不是值发出时才编译的:

#include <QObject>

class mythirdclass {
public:
    mythirdclass();
};

class mysecondclass : public QObject, public mythirdclass {
public:
    mysecondclass(mythirdclass third);
};

class myclass : public QObject {
    Q_OBJECT
public:
    myclass();

signals:
    // not working
    void messageReceived(mysecondclass mymessage);
    // working
    // void messageReceived(mysecondclass &mymessage);
};

myclass::myclass()
{
    mythirdclass third;
    mysecondclass msg(third);
    emit messageReceived(msg);

}

mysecondclass::mysecondclass(mythirdclass third)
{
    // DO stuff
}

mythirdclass::mythirdclass()
{
}

编译器错误是:

..\example\main.cpp: In constructor 'myclass::myclass()':
..\example\main.cpp:28:20: error: use of deleted function 'mysecondclass::mysecondclass(const mysecondclass&)'
  emit signal(second);
                    ^
..\example\main.cpp:8:7: note: 'mysecondclass::mysecondclass(const mysecondclass&)' is implicitly deleted because the default definition would be ill-formed:
 class mysecondclass : QObject, public mythirdclass {
       ^

基于这些错误,我认为正在为mysecondclass编写一个副本构造mysecondclass ,但是经过一些尝试之后,我暂时放弃了,因为我mysecondclass了。

所以我的问题是:

  • 为什么编译首先失败?
  • 如果由于缺少副本构造函数而失败,为什么编译器无法隐式定义一个?
  • 在我的情况下,工作副本构造函数是什么样的?

提前致谢。

为什么编译首先失败?

因为按值传递意味着复制,并且如果删除了复制构造函数,则它根本无法按值传递,并且您的函数无法使用此签名进行编译,而它可以通过引用接收其参数,因为它不涉及复制。

如果由于缺少副本构造函数而失败,为什么编译器无法隐式定义一个?

它实际上失败了,因为它无法隐式定义一个。 这样做的原因是您的类是从QObject派生的。 而且, QObject 在设计上没有公共或受保护的复制构造函数 因此,编译器无法隐式定义一个。

在我的情况下,工作副本构造函数的外观如何?

考虑到QObject的性质,以及当QObject不可复制时背后的设计决策,我建议不要使用采用QObject或通过值派生自其的类或类的信号和插槽(或简单地执行以及信号/插槽主要是在内部深层起作用的),而是通过引用或指针来实现。

对于您的第三个问题,如果您不想为mysecondclass定义默认构造函数,则复制构造函数可能看起来像

 mysecondclass(mysecondclass const &other) : mythirdclass() {
    /// stuff
 }

对于第二个问题,我想(不确定)默认副本构造函数尝试使用已自动删除的默认构造函数,因为您已经从mythirdclass对象定义了mysecondclass的另一个构造函数(我建议您使用const参考此处的参数以避免不必要的复制)

暂无
暂无

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

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