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

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

我读到 qt 中的 signal/slot 概念应该始终按值而不是引用传递参数,以确保 signals/slots 在线程之间完美地工作。

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

#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(mysecondclass const &other) : mythirdclass() {
    /// stuff
 }

关于你的第二个问题,我想(不确定)默认复制构造函数尝试使用已自动删除的默认构造函数,因为你已经从 mythirdclass 的对象定义了另一个 mysecondclass 的构造函数(我建议你在这里为参数使用 const 引用以避免无用的复制)

Why is the compiling failing in the first place?

因为按值传递意味着复制,如果复制构造函数被删除,那么它就不能按值传递,你的函数不能用这个签名编译,但它可以通过引用接收它的参数,因为它不涉及复制。

If it fails because of a missing copy constructor, why is the compiler not able to define one implicitly?

它实际上失败了,因为它无法隐式定义一个。原因是您的 class 派生自 QObject。而且 QObject doesn't have a public or protected copy-constructor,是设计使然。所以编译器不能隐式定义一个。

How would the working copy constructor in my case look like?

鉴于 QObjects 的性质,以及涉及 QObjects 不可复制时背后的设计决策,我建议不要使用采用 [=10] 的信号和插槽=]s 或 class 按值从它派生(或者只是执行此操作的任何函数,而 signals/slots 主要是深层函数),而是通过引用或指针。