33

这是我在 const-ref 中从未得到过的东西,我真的希望有人可以向我解释。

在另一个函数内部调用一个函数时,我知道 const-ref 是传递我不打算篡改的堆栈对象时的最佳方式。例如:

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

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

到目前为止一切顺利,我猜。但是信号呢?传递参考是否有任何风险?尽管它是const. 感觉就像我一直在阅读所有关于 const-ref 的文档,但我仍然觉得有点冒险,因为我将其理解为“发送对对象的引用并保留它const”。如果它所指的对象超出范围怎么办?

例如:

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?
}

这里到底发生了什么?我经常在函数调用中使用 const-ref,我只想访问对象但不更改它。但是信号呢?大多数信号似乎在 Qt 文档中都有 const-ref parm,但它是如何工作的?

4

3 回答 3

26

根据这个答案,Qt 只是用副本替换 const 引用。

编辑:显然并非总是如此......我只是用一个线程做了一个基本的测试程序,并且引用被正确传递。它的 const-ness 也保持不变。无论如何,是的,您确实需要警惕变量超出范围,而且您不能以这种方式跨线程发送引用。如果这样做,则只会传递副本。

要回答您示例评论中的问题,是的,无论是直接连接还是排队连接,它都会起作用。如果是直接连接,它将工作,因为someSlot()将在someFunction()完成之前执行;如果它是排队连接,它将起作用,因为test它将被复制而不是通过引用传递。

于 2012-05-01T23:44:08.323 回答
4

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

于 2015-04-29T13:48:12.267 回答
0

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

于 2012-05-02T01:23:07.957 回答