2017-04-19 84 views
4

閱讀Qt signal & slots documentation,似乎新風格連接失敗的唯一原因是: 「如果已經有一個重複(完全相同的信號到同一對象上完全相同的插槽),連接將失敗,連接將返回false「當Qt-5將失敗時,連接

這意味着連接在第一次已經成功,並且在使用Qt :: UniqueConnection時不允許多連接。

這是否意味着Qt-5風格的連接總會成功?是否有其他原因失敗?

回答

4

的新型connect在運行時仍可能會失敗各種它可能會失敗原因:

  • senderreceiver一個空指針。顯然這需要一個只能在運行時發生的檢查。
  • 您爲信號指定的PMF實際上不是一個信號。由於缺乏適當的C++反射功能,您在編譯時所能做的就是檢查信號是發送者類的非靜態成員函數。

    但是,這還不足以使其成爲一個信號:它也需要位於類定義中的signals:部分。當moc看到你的類定義時,它將生成some metadata,其中包含該函數確實是信號的信息。因此,在運行時,傳遞到connect的指針在表中查找,如果找不到指針(因爲您沒有傳遞信號),connect本身將失敗。

  • 對前一點的檢查實際上需要比較指向成員函數的指針。這是一個特別棘手的一個,因爲它通常涉及不同的TU:

    1. 一個是含有MOC生成的數據的TU(典型地爲moc_class.cpp文件)。在這個TU中有上述表格,其中包含指向信號的指針(這些指針只是普通的成員函數)。
    2. 是您實際調用connect(sender, &Sender::signal, ...)的TU,它生成在表中查找的指針。

    現在,這兩個TU可能在同一個應用程序中,或者一個在一個庫中,另一個在您的應用程序中,或者可能在兩個庫中等;你的平臺ABI開始發揮作用。

    理論上,做1時存儲的指針與做2時產生的指針相同。在實踐中,我們發現了這種情況沒有發生的情況。這是我前段時間報告的bug report,其中ARM上較舊版本的GNU ld生成的代碼未通過比較)。

    對於Qt,這意味着禁用某些優化和/或將一些額外的標誌傳遞到我們知道發生這種情況並破壞用戶軟件的地方。例如,從Qt 5.9開始,除了x86和x86-64之外,不支持GCC上的-Bsymbolic*標誌。

    當然,這並不意味着我們已經找到並修復了全部可能的地方。新的編譯器和更積極的優化可能會在未來再次觸發此錯誤,使connect返回false,即使所有事情都應該起作用。

-2

不,它並不總是成功。該文檔給出了一個示例here,其中connect將返回false,因爲該信號不應包含變量名稱。

// WRONG 
QObject::connect(scrollBar, SIGNAL(valueChanged(int value)), 
      label, SLOT(setNum(int value))); 
+1

這不是Qt5式連接 –

+0

你是對的。 Appologies。 – user2027202827

2

是如果任一發送者或接收者都無效對象(nullptr例如)

QObject* obj1 = new QObject(); 
QObject* obj2 = new QObject(); 
// Will succeed 
connect(obj1, &QObject::destroyed, obj2, &QObject::deleteLater); 
delete obj1; 
obj1 = nullptr; 
// Will fail even if it compiles 
connect(obj1, &QObject::destroyed, obj2, &QObject::deleteLater);