[英]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.