简体   繁体   English

在Qt中发送信号时的const-ref

[英]const-ref when sending signals in Qt

This is a thing that I never quite got with const-ref and I really hope that someone could explain it to me. 这是我从来没有用const-ref得到的东西,我真的希望有人可以向我解释。

When calling a function inside of another function, I get that const-ref is the best way when passing stack objects that I don't plan to tamper with. 当调用另一个函数内部的函数时,我得到的const-ref是传递我不打算篡改的堆栈对象的最佳方法。 For example: 例如:

void someInnerFunction(const QString& text) {
    qDebug() << text;
}

void someFunction() {
    QString test = "lala";
    ....
    someInnerFunction(test);
}

So far so good, I guess. 到目前为止,我觉得这么好。 But what about signals? 但信号怎么样? Isn't there any risk that comes with passing a reference? 传递参考文件是否存在任何风险? Even though it's const . 即使它是const It feels like I've been reading all the docs about const-ref but I still find a bit risky since I understand it as "sending a reference to an object and keeping it const ". 感觉就像我一直在阅读关于const-ref的所有文档但我仍然觉得有点冒险,因为我把它理解为“发送一个对象的引用并保持它的const ”。 What if the object it's referring to goes out of scope? 如果它所指的对象超出范围怎么办?

For example: 例如:

void someFunction() {
    connect(this, SIGNAL(someSignal(const QString&)), this, SLOT(someSlot(const QString&)));

    QString test = "lala";
    emit someSignal(test);

    // doesnt test go out of scope here? and since im not using queued connection the QString object doesnt get copied. 
}

void someSlot(const QString& test) {
    qDebug() << test; // will this work?
}

What is really happening here? 这里到底发生了什么? I frequently use const-ref on function calls where I just want to access the object but not change it. 我经常在函数调用中使用const-ref,我只想访问该对象但不更改它。 But what about signals? 但信号怎么样? Most signals seems to have const-ref parm in the Qt doc, but how does it work? 大多数信号在Qt doc中似乎都有const-ref parm,但它是如何工作的?

According to this answer , Qt just replaces const references with copies. 根据这个答案 ,Qt只是用副本替换const引用。

EDIT: Apparently not always the case... I just did a basic test program with one thread, and the reference was passed correctly. 编辑:显然并非总是这样...我只是用一个线程做了一个基本的测试程序,并且正确传递了引用。 Its const-ness remained intact, as well. 它的常数也保持不变。 Anyways, yes, you do need to be wary of the variable going out of scope, plus you can't send references across threads this way. 无论如何,是的,你确实需要警惕超出范围的变量,而且你不能以这种方式跨线程发送引用。 If you do, only copies will be passed. 如果您这样做,只会传递副本。

To answer the questions in the comments of your example, yes, it will work regardless of whether it's a direct or queued connection. 要回答示例评论中的问题,是的,无论是直接连接还是排队连接,它都能正常工作。 If it's a direct connection, it will work because someSlot() will be executed before someFunction() finishes; 如果它是直接连接,它将起作用,因为someSlot()将在someFunction()完成之前执行; if it's a queued connection, it will work because test will be copied instead of passed by reference. 如果它是一个排队连接,它将起作用,因为test将被复制而不是通过引用传递。

这是一个很好的演示,展示了Qt信号/插槽如何管理复制: http//www.embeddeduse.com/2013/06/29/copied-or-not-copied-arguments-signals-slots/

在Qt中,当发出连接到插槽或插槽的信号时,它等同于同步函数调用...除非你已经将信号和插槽配置为使用排队连接,那么它是异步调用,你应该是传递堆栈数据时要小心,并且应该传递副本,就像将数据传递给另一个线程一样。

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

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