Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使Qt信号按值发出而不产生编译错误而不是引用?_C++_Qt_Copy Constructor_Qt Signals - Fatal编程技术网

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

C++ 如何使Qt信号按值发出而不产生编译错误而不是引用?,c++,qt,copy-constructor,qt-signals,C++,Qt,Copy Constructor,Qt Signals,我读到qt中的信号/插槽概念应该总是通过值而不是引用来传递参数,以确保信号/插槽在线程之间完美地工作 我现在有一段代码,只有当信号的参数通过引用而不是值发出时,它才会编译: #include <QObject> class mythirdclass { public: mythirdclass(); }; class mysecondclass : public QObject, public mythirdclass { public: mysecondclas

我读到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()
{
}
基于这些错误,我曾考虑为
mysecondclass
编写一个副本构造函数,但是经过一些尝试之后,我现在放弃了,因为我没有正确地编写它

因此,我的问题是:

  • 为什么编译首先会失败
  • 如果由于缺少复制构造函数而失败,为什么编译器不能隐式定义一个
  • 在我的例子中,工作副本构造函数是什么样子的

提前感谢。

对于第三个问题,如果您不想为mysecondclass定义默认构造函数,那么您的复制构造函数可能如下所示

 mysecondclass(mysecondclass const &other) : mythirdclass() {
    /// stuff
 }
对于第二个问题,我假设(不确定)默认复制构造函数尝试使用已自动删除的默认构造函数,因为您已从mythirdclass的对象中定义了mysecondclass的另一个构造函数(我建议您在此处使用参数的常量引用,以避免无用的复制)

为什么编译首先会失败

因为按值传递意味着复制,如果复制构造函数被删除,那么它就不能按值传递,并且您的函数不能使用此签名进行编译,而它可以通过引用接收其参数,因为它不涉及复制

如果由于缺少复制构造函数而失败,为什么编译器不能隐式定义一个

它实际上失败了,因为它无法隐式地定义一个。原因是您的类派生自
QObject
。而且是设计的
QObject
。因此编译器不能隐式定义一个

在我的例子中,工作副本构造函数是什么样子的


考虑到
QObject
s的性质,以及当涉及到
QObject
s不可复制时,其背后的设计决策,我建议不要使用采用
QObject
s的信号和时隙,或者使用从其派生的值类(或者简单地说是任何这样做的函数,信号/插槽主要是深层的函数),而是通过引用或指针。

感谢关于
const&
的提示,我将把构造函数更改为
mysecondclass::mysecondclass(const thirdclass&third)
。我还添加了一个默认构造函数,只是忘记了它。这种
mysecondclass::mysecondclass()的存在
但是不会改变编译错误。你的
mysecondclass
不是故意继承
public QObject
…你是对的,忘记了。这是完整的代码吗?@JBL这是一个很小的例子。现实世界的场景是
myclass
是一个包装类,它连接
QCanBusDevice
QCanBusFrame
mythirdclass
是一个
QCanBusFrame
mysecondclass
是我在应用层的任何地方使用的一个特定消息类。这是相关的:感谢您的深入解释!只要我没有遇到任何与信号发射和多重区域相关的问题,我将参考丁。
 mysecondclass(mysecondclass const &other) : mythirdclass() {
    /// stuff
 }