Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

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. 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. 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". 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. But what about signals? Most signals seems to have const-ref parm in the Qt doc, but how does it work?

like image 728
chikuba Avatar asked May 01 '12 23:05

chikuba


People also ask

Can Qt signals be const?

Nothing prevents a Qt signal to be const AFAIK (tested with Qt5. 9). The answer from IInspectable is not correct. - call non-const methods on the sender() .

How to connect signals and slots in Qt?

To connect the signal to the slot, we use QObject::connect(). There are several ways to connect signal and slots. The first is to use function pointers: connect(sender, &QObject::destroyed, this, &MyObject::objectDestroyed);


2 Answers

According to this answer, Qt just replaces const references with copies.

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; if it's a queued connection, it will work because test will be copied instead of passed by reference.

like image 127
Anthony Avatar answered Oct 13 '22 08:10

Anthony


Here is a good demonstration showing how Qt signals/slots manage copying: http://www.embeddeduse.com/2013/06/29/copied-or-not-copied-arguments-signals-slots/

like image 39
user2449761 Avatar answered Oct 13 '22 06:10

user2449761