【问题标题】:connect const QString& or const QString连接 const QString& 或 const QString
【发布时间】:2013-01-08 14:02:17
【问题描述】:

如果 QString 是本地的,那么使用 QString 发出信号的正确方法是什么。 我的意思是我在 wigdetA 中有这样的功能

void wigdetA::something()
{

//
//e.g
//
QTreeWidgetItem *it = this->treeWidget->currentItem();
if (it == 0)
    return;

QString s = it->text(1);

emit passToMainWindow(s);
}

我应该像这样创建连接吗(只是 const QString):

 connect(wigdetA, SIGNAL(passToMainWindow(const QString)), this, SLOT(passToMainWindow(const QString)));

或者我可以使用 const 引用

connect(wigdetA, SIGNAL(passToMainWindow(const QString&)), this, SLOT(passToMainWindow(const QString&)));

两种方法都可以,但我认为第二个 const& 会使应用程序崩溃,因为 QString s 是本地的,并且当函数 something() 退出时它将被销毁。

或者我错过了什么?

【问题讨论】:

    标签: qt


    【解决方案1】:

    由于发射和接收对象都在主线程中,Qt 使用直接连接(当您发出时立即调用插槽)。在这种情况下,您的本地字符串仍在堆栈中。

    但是,通过值传递它总是更好,尤其是在驻留在不同线程中的对象之间建立连接时。 QString 使用隐式共享(即写时复制),因此按值传递它的成本并不高。

    【讨论】:

    • 这是错误的。跨线程信号被排队(参见 Qt::QueuedConnection),因此在每种情况下都会复制值,并且使用 const 引用是安全的。因此,人们始终可以安全地使用 const 引用。
    • @Frank,是的,你是对的,感谢您的纠正。默认情况下,跨线程连接排队。对于排队连接,确实会调用一个复制构造函数(为了通过排队连接传递一个对象,必须要有复制构造函数)。对于直接连接,如果声明,对象将通过引用传递(省略复制)。但是没有必要写 SIGNAL(pass(const QString&)); SIGNAL(pass(QString)) 对这两种情况都很好。
    • 对于连接语句,这是正确的。对于信号/槽签名,应该使用 const & 虽然。
    【解决方案2】:

    对于 Qt5,新的连接系统要求两个插槽具有相同的参数类型,并且将带有 QString 参数的信号连接到带有 const QString & 的插槽将不起作用。

    ObjType1 : QObject {
      Q_OBJECT
      ...
      signals :
      sendInfo(QString)
    }
    
    ObjType2 : QObject {
      Q_OBJECT
      ...
      public slots:
      slotObjType1::receiveInfo(const QString&)
      ...
    }
    
    void ObjTyp3::someFunction{}(
       ...
       connect(mpObj1, &ObjType1::sendInfo, mpObj2, &ObjType2::receiveInfo); // shows an error because arguments does not match
       ...
    }
    

    如果我们考虑多线程问题,那么按值传递将是更安全、更可维护的做事方式。 但是,许多文档显示带有“const QString&”参数的插槽,尽管它不允许连接带有 QString 参数的信号。 当不使用直接连接时,复制 (const QString &) 值的“连接”机制有什么魔力吗?每个人都使用带有 QString 参考的信号有理由吗?

    【讨论】:

    • 似乎连接机制在不使用直接连接时会复制参考值:stackoverflow.com/questions/42187235/…
    • 所以使用"const QString &" 是最好的,因为它在使用直接连接时会更轻,并且会在线程间通信的情况下处理
    【解决方案3】:

    emit passToMainWindow(s) 将在发出时调用主窗口中的插槽。所以这没什么大不了的。在处理他们主要使用的 qt 插槽时,const QString& 所以我猜框架会注意字符串在被插槽使用之前不会被删除。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-13
      • 2012-10-02
      • 2014-01-16
      • 1970-01-01
      • 2013-09-30
      • 2015-11-06
      • 1970-01-01
      相关资源
      最近更新 更多