2015-04-06 78 views
0

我在KDE軟件中遇到過一些情況,其中一個是KPart的dynamic_cast在OS X上失敗。我不是一個C++專家,所以我甚至不知道從哪裏開始調試這樣一個情況。 我已經看到這種情況發生與ktimetracker,以及最新的(和更好的討論)情況是Okular中:https://bugs.kde.org/show_bug.cgi?id=345765當dynamic_cast失敗時,這意味着什麼?

一言以蔽之:在Okular::Part類繼承的類Okular::ViewInterface(作爲最後一個父列表中的)。然而當代碼檢索到Okular::Part*實例(part)時,dynamic_cast<Okular::ViewInterface*>(part)返回NULL。

上面BKO票券的最後一個評論是,在這種情況下使用靜態轉換將是一個窮人的修復,但是我應該嘗試弄清楚爲什麼dynamic_cast失敗。這導致我有2個問題:

  • 除了這裏的傳統演員,dynamic_cast還有什麼作用?
  • 我該如何找出失敗的原因?這將是運行時,libC++,否的問題?
+0

在鑄造班級時,某種原因喜歡(彷彿)鑄造結構的程度如何?我想,真正重要的是類變量,而不是類的功能? – RJVB 2015-04-09 19:13:21

回答

0

Thiago Macieira就Qt利益ML提供了讓我解決問題的答案。我在這裏將其複製:

在這個 這類問題通常犯罪嫌疑人是一樣的:你的虛擬表不正確固定在 共享庫。

確保參加這個派對的所有類檢查所有這些框:
*必須在類聲明的出口宏
*主虛擬功能是一個.cpp,NEVER直列

主要虛函數是 父類的順序中的第一個新覆蓋的函數,或者如果沒有被覆蓋,則爲第一個新虛函數。 通常,多態類具有虛擬析構函數,而且破壞函數總是被覆蓋,所以這是最好的選擇。

在這種情況下,問題是由於目標類(Okular :: ViewerInterface)未在OS X上導出(可能默認情況下或因爲Linux上的全局編譯器開關)。同樣適用於KDocumentViewer類,但可能不相關。

1

這意味着指針指向的對象的繼承層次結構中沒有Okular::Part(我忽略了涉及多繼承的某些邊案例)。因此,動態投射失敗。

這就是這個意思。儘管如此,它並不能真正幫助您理解最初引用的錯誤。

+0

唉唉 類Okular中::部分:公共的KParts :: ReadWritePart,公共Okular中:: DocumentObserver,公共KDocumentViewer,公共Okular中:: ViewerInterface {} 但實例代碼試圖做的dynamic_cast是的KParts :: ReadWritePart * 。我不能以任何方式看到Okular :: ViewInterface的後代。 如果我的理解正確,那將解釋這個問題? – RJVB 2015-04-06 21:50:50

+0

如果是這樣,問題(幾乎)變成:爲什麼在Linux上這不會失敗?我在OP中沒有提到它,但它在那裏工作,使用gcc和clang。這也解釋了爲什麼我想到libC++:這是我能想到的唯一相關的事情。但那是檢查的運行時間,我認爲? – RJVB 2015-04-06 21:54:02

+0

是的,dynamic_cast在運行時進行評估。但是,請注意,這種動態轉換可能會成功的一種方式是,如果不同的類將Okular :: ViewInterface和dynamic_cast所屬的類分開來。 – 2015-04-06 22:13:55

1

除了這裏的傳統演員,dynamic_cast還有什麼功能?

它執行運行時檢查轉換是否有效;指針確實指向正確類型的對象。

我該如何弄清楚爲什麼它會失敗?

如果Part真的是從ViewInterface衍生,那麼就不能失敗,如果指針指向一個有效Part對象。所以對象必須已經被破壞或者被破壞。像Valgrind這樣的動態分析工具可以幫助診斷這類問題。

這將是運行時的問題,libC++,no?

幾乎肯定不是。這很可能是管理對象的生命週期的問題,最後是一個懸掛指針。或者它可能是一個其他地方破壞對象的錯誤,所以它不再包含有效的RTTI信息。或者,因爲似乎涉及到線程,也許它沒有足夠的同步而被共享。

靜態投將是一個窮人的修復

它不會解決任何事情。您將以不同的方式獲得不確定行爲的不同風格。

相關問題