在qt從4到5的升級過程中,connect的方法只是添加了一些重載的形式,qt5新增的connect添加了編譯器類型檢查,如果遇到匹配失敗的,或者找不到信號/槽的地方,會直接報錯,而不是qt4到運行期才告訴用戶。新版本qt在connect的支持方面是兼容以前的老版本的,因此在以前使用qt4.x,而現在升級到qt5.x的項目大可以不更改這些connect。
新版本的connect,使用函數指針能夠獲得編譯期的類型檢查,而這樣也有弊端,當遇到重載信號槽的時候在編譯器就會報錯,說 “無法將參數 2 從“overloaded-function”轉換為“const char *”上下文不允許消除重載函數的歧義。
針對以上問題,我們首先分析錯誤原因,編譯器無從知道信號/槽具體調用的是哪個方法,因此我們介紹兩種方式來解決這個問題。
- 方式1:手動聲明一個函數指針,指向目標的信號/槽方法;
- 方式2:使用C++的靜態類型轉換。
針對以上兩種方式,給處如下事例
方式1事例如下:
void (ClassA:: *p)(QString, QDate) = &ClassA::signalFunciton;
QObject::connect(&a, p, &b, &Reader::slotFunction);
或者
QObject::connect(&a,(void (ClassA:: *)(QString, ))&ClassA::signalFunciton, b, &ClassB::slotFunction);
方式2事例如下:
QObject::connect(&a, static_cast<void (ClassA:: *)(QString)>(&ClassA::signalFunction), &b, &ClassB::slotFunction);
對比上面兩種寫法。第一個使用的是 C 風格的強制類型轉換。此時,如果你改變了信號的類型,那么你就會有一個潛在的運行時錯誤。例如,如果我們把 (QString, QDate) 兩個參數修改成 (QDate, QString),C 風格的強制類型轉換就會失敗,並且這個錯誤只能在運行時發現。而第二種則是 C++ 推薦的風格,當參數類型改變時,編譯器會檢測到這個錯誤。
注意,這里我們只是強調了函數參數的問題。如果前面的對象都錯了呢?比如,我們寫的a對象並不是一個 signalFunction,而是 signalFunction2?此時,編譯器會直接失敗,因為 connect() 函數會去尋找 sender->*signal,如果這兩個參數不滿足,則會直接報錯。
寫這個博文的時候其實是想寫qt的多語化的,不過不要緊,馬上寫,事例代碼都已經准備OK了
如果您覺得文章不錯,不妨給個
打賞,寫作不易,感謝各位的支持。您的支持是我最大的動力,謝謝!!!