2012-07-13 59 views
2

一些背景優先:多級繼承和dynamic_cast

我正在研究一些實現UI接口的遺留代碼。代碼的構造方式是它有一個基類(實際上是一個結構體),然後將其導出到各種圖形對象。

WinBase: 
- Button 
- DialogWin 
- (etc...) 
- EditWin 

勝基具有用來密切關注所有每個對象的孩子中的一員WinBase **children。這些孩子在運行期間以標準的new []/delete []方式創建和銷燬。

這些對象的所有方法/函數都假定它們正在接收指向WinBase對象的指針,並且dynamic_cast<>用於確保/驗證是否正在使用適當的指針。

稍後改變到代碼增加了兩個類/結構(ListBoxTextBox)時,從EditWin而這又是從WinBase衍生而得。

所以...我有指向WinBase,它被鑄造爲ListBoxTextBox。正如我所說,在整個代碼中都使用了dynamic_cast<>,但我不確定在調用像這個構造函數這樣的函數時它有多安全。

如何安全是直接從WinBase轉換爲ListBox,反之亦然(例如)?

+1

以什麼方式安全?如果運行時類型不允許轉換,dynamic_cast <>'將評估爲NULL指針。只要你檢查結果是非空的,你就很安全。如果這不是問題,那麼您確實需要提供更多細節,以及您特別困惑的代碼(以及以何種方式)。 – pmdj 2012-07-13 11:45:58

+0

而不是返回0,如果我沒有弄錯,它會拋出一個'std :: bad_cast'異常。 – jogojapan 2012-07-13 11:48:22

+1

@jogojapan如果使用指針,總是返回0。 – ForEveR 2012-07-13 11:49:24

回答

0

首先,爲什麼你想投一個WinBaseListBox當一個ListBox被給予期待WinBase的方法?如果你需要在那裏演員,你應該重新考慮設計,因爲期望WinBase只能在WinBase's接口上操作的方法。

如果且僅當,ListBoxWinBase(直接或間接地)衍生的,可以隨時從ListBox*轉換爲WinBase*(或參考),因爲一個列表框IS AWinBase

以另一種方式投射並不安全,因爲您永遠不會知道您得到的WinBase*實際上是ListBox*還是別的什麼,這就需要麻煩。您當然可以使用dynamic_cast<>來測試它是否爲ListBox*,但任何動態演員都需要審查您的設計。

特別是那種在構造函數中調用麻煩的下調函數,因爲當你沒有得到你想要的東西時,你的代碼應該做什麼?拋出異常,作爲唯一的出路不是這樣一個好主意,並在最好的avoided at all(除非你知道你在做什麼)。

+0

有問題的代碼是遺留代碼,因此作者可能無法重新設計它以避免動態轉換。而'dynamic_cast'並不總是一件壞事。像其他所有內容一樣,它有其用途,即[非週期性訪問者](http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CE8QFjAA&url=http%3A%2F%2Fwww .objectmentor.com%2Fresources%2Farticles%2Facv.pdf&EI = VhIAUNDpMsLj0QG2z7H0Bw&USG = AFQjCNGMyoy2E1JAuc_3CHEZnsq_nS8H4Q)。 – 2012-07-13 12:20:27

+0

當然,那是真的。然而,OP似乎並不十分熟悉C++的繼承細節,這些細節很容易被瀏覽到。我的意圖是指出兩個方向都可以,一個總是安全的,另一個是,不是:-) – 2012-07-13 12:40:11

+0

因爲我改變了這段代碼,我一直在閱讀有關繼承的微妙之處;)和我的主要這裏值得關注的是,如果我可以在向WinBase上傳時跳過中間對象,或者我必須執行一系列強制轉換以達到基類。 – 2012-07-13 13:23:36