這里的一些答案使得通過C+類聽起來真的很可怕,但我想分享另一個觀點。其他一些響應(yīng)中提到的純虛擬C+方法實際上比您想象的要干凈。我已經(jīng)圍繞這個概念建立了一個完整的插件系統(tǒng),它已經(jīng)運行了很多年了。我有一個“PluginManager”類,它使用LoadLib()和GetProcAddress()動態(tài)地從指定的目錄加載dll(以及Linux等效文件,以便跨平臺執(zhí)行)。
信不信由你,即使您做了一些奇怪的事情,比如在純虛擬界面的末尾添加一個新函數(shù),并嘗試在沒有新函數(shù)的情況下加載針對接口編譯的dll,這種方法也是可以原諒的-它們會加載得很好。當(dāng)然.。您必須檢查版本號,以確保您的可執(zhí)行文件只對實現(xiàn)該函數(shù)的較新的dll調(diào)用新函數(shù)。但好消息是:它有效!因此,在某種程度上,你有一個粗糙的方法來逐步發(fā)展你的界面。
關(guān)于純虛擬接口的另一件很酷的事情-你可以繼承你想要的多少接口,你永遠(yuǎn)不會遇到鉆石問題!
我想說,這種方法最大的缺點是,您必須非常小心您作為參數(shù)傳遞的類型。不首先用純虛擬接口包裝類或STL對象。沒有結(jié)構(gòu)(沒有經(jīng)過實用主義包裝巫毒)。只是原始類型和指向其他接口的指針。此外,您不能超載函數(shù),這是一個不便,但不是一個顯示停止。
好消息是,使用少量代碼行,您可以創(chuàng)建可重用的泛型類和接口來包裝STL字符串、向量和其他容器類。或者,您可以將函數(shù)添加到您的接口中,如GetCount()和GetVal(N),以便讓用戶遍歷列表。
人們?yōu)槲覀儤?gòu)建插件很容易。他們不必是ABI邊界方面的專家-他們只是繼承他們感興趣的接口,對他們支持的函數(shù)進行編碼,并為不支持的函數(shù)返回false。
據(jù)我所知,制造所有這些工作的技術(shù)并不是基于任何標(biāo)準(zhǔn)。據(jù)我所知,微軟決定這樣做他們的虛擬表,這樣他們就可以制作COM,而其他編譯器編寫人員也決定效仿。這包括GCC、Intel、Borland和其他大多數(shù)主要的C+編譯器。如果您計劃使用一個晦澀的嵌入式編譯器,那么這種方法可能不會適用于您。理論上說,任何一家編譯器公司都可以隨時改變他們的虛擬表并打破它們,但是考慮到多年來編寫的大量代碼依賴于這種技術(shù),如果任何主要的參與者決定打破排名,我會感到非常驚訝。
所以這個故事的寓意是.。除了一些極端的情況外,您需要一個負(fù)責(zé)接口的人,他可以確保ABI邊界與原始類型保持干凈,并避免重載。如果您同意這一規(guī)定,那么我就不怕在編譯器之間共享DLL/SOS中類的接口。直接共享類=麻煩,但共享純虛擬接口并不那么糟糕。