当Qt-5连接失败时

use*_*767 5 qt qt5

阅读Qt信号和插槽文档,似乎新样式连接失败的唯一原因是:"如果已经有重复(完全相同的信号到相同对象上完全相同的插槽),连接将失败并连接将返回虚假"

这意味着第一次连接已经成功,并且在使用Qt :: UniqueConnection时不允许多连接.

这是否意味着Qt-5风格的连接将永远成功?还有其他原因导致失败吗?

pep*_*ppe 5

由于connect各种原因,新样式仍然可能在运行时失败:

  • 要么sender或者receiver是一个空指针.显然,这需要进行只能在运行时进行的检查.
  • 您为信号指定的PMF实际上不是信号.缺乏正确的C++反射功能,您在编译时可以做的就是检查信号是发送方类的非静态成员函数.

    但是,这还不足以使它成为一个信号:它还需要signals:位于类定义的一个部分中.当moc看到您的类定义时,它将生成一些元数据,其中包含该函数确实是信号的信息.因此,在运行时,传递给的指针会connect在表中查找,connect如果找不到指针,则本身会失败(因为您没有传递信号).

  • 对前一点的检查实际上需要在指向成员函数的指针之间进行比较.这是一个特别棘手的问题,因为它通常涉及不同的TU:

    1. 一个是包含moc生成的数据(通常是moc_class.cpp文件)的TU .在这个TU中,上面提到的表包含指向信号的指针(它们只是普通的成员函数).
    2. 是您实际调用的TU connect(sender, &Sender::signal, ...),它生成在表中查找的指针.

    现在,这两个TU可能在同一个应用程序中,或者可能是一个在库中,另一个在您的应用程序中,或者可能在两个库中等; 你的平台的ABI开始发挥作用.

    理论上,在执行1时存储的指针与执行2时生成的指针相同.在实践中,我们发现了这种情况不会发生的情况(参见我之前报告的这个错误报告,其中旧版本的GNU ld on ARM生成的代码未通过比较).

    对于Qt,这意味着禁用某些优化和/或将一些额外的标志传递给我们知道发生这种情况并破坏用户软件的地方.例如,从Qt 5.9开始,-Bsymbolic*除了x86和x86-64之外,GCC上的标志都不支持.

    当然,这并不意味着我们找到并修复了所有可能的地方.新的编译器和更积极的优化可能在将来再次触发此错误,使得connect返回错误,即使一切都应该工作.