2011-04-15 41 views
3

基本密新行爲考慮現有的C++類層次結構:一個根類,很多孩子班級形成了向無環圖。如何代表C++

我想一個方法添加到根類,並可能覆蓋它在一些兒童。 但問題是,它是被禁止的,我修改這些現有的類(第三方庫,項目政策,封閉源代碼,等等)。然後

一個混合/擴展類將是一個很好的解決方案。但它在C++中並不可行。

的快速和骯髒的解決方案是將寫上使用 的的dynamic_cast操作員,以及執行想要的代碼給每個類型的層次結構的對象的類型將調度功能。但這是一種不好的做法,因爲 它容易出錯,它破壞了封裝,並且不支持安全的將來更改。

我的想法與定義保持某種哈希表的地方{RTTI類型ID,功能調用}」,並用它作爲 一個假的虛函數表因爲我想寫的功能和重寫但我不知道這是否會更好......

任何其他的想法運行虛函數表改造模板元編程解決方案的其他

不要忘了:????我明確不能改變原來的類(既沒有標題也沒有實現)。

回答

2

如果您無法更改原始層次結構,那麼模板元編程不太可能有所幫助。請記住它基於編譯時信息。

改變vtable看起來是一個非常糟糕的主意,它顯然是不可移植的,並假設你有點了解它的物理佈局......即使你做對了,它也將是一個維護噩夢。

我很喜歡std::map<type_info, Func>想法。 std::type_info::before爲您提供實施所需的一切(不要依賴名稱或地址)。

+0

好吧,然後我將使用std :: map 系統。感謝advince :: before。 – 2011-04-18 18:03:31

1

寫一個免費的功能。

void vfunc(base& param); 

// ... 
base b; 
vfunc(b); 

deriv0 d0; 
vfunc(d0); 
+1

那就是我所做的,並且在類型上使用dynamic_cast來模擬方法覆蓋。但我認爲這不是一個很好的做事方式。我正在尋找的是一個更乾淨的方式來做到這一點(比如運行時Mixins等) – 2011-04-15 12:42:16

+0

我不明白。你爲什麼需要'dynamic_cast'?如果你需要多態,那麼上面的函數簽名就是你所需要的。如果您需要編譯時多態性,請將其作爲模板。如果您希望層次結構中每個類的特定行爲,並且沒有其他類,則會重載該函數。 – wilhelmtell 2011-04-15 12:50:17

+2

除了如果我重載「deriv0」的函數,但只有一個指向「base」(可能是「deriv0」或「deriv1」等的實例)的指針,重載函數將不會被調用,函數調用僅在編譯時類型上調度。 – 2011-04-15 13:10:36

2

其實我在寫,不只是一個庫:可讓您撰寫並在運行時從現有的類修改的類型,與不能夠調用的方法是......呃方法的成本,但由於外部函數的第一個參數this。這是非侵入式的,所以你不需要以任何方式修改現有的類。

代碼:https://github.com/iboB/boost.mixin

文件:http://ibob.github.io/boost.mixin/

希望它幫助。

PS。它被稱爲Boost.Mixin,因爲我打算將它提交給Boost,但它不是Boost的一部分。