2012-09-14 62 views
3

我有一個父類「基」和另一個繼承自「基」的類「派生」。dynamic_cast vs暴露父類中的虛函數(C++)

「派生」有1個方法cH1。

如果我這樣做:

base* b = new derived(); 

而且我希望能夠做到這一點:

b->cH1(); 

很明顯,我不能和有2個解決方案:

  • 將基地中的cH1聲明爲純虛擬。
  • 或做到這一點:

    dynamic_cast<derived*>(b)->cH1(); 
    

哪一個是一個更好的做法?

+2

請關掉你的大寫鎖定鍵; 'PARENT'表明這個名字是一個宏; '父母'是通常的用法。 –

+1

我想說,你頭上最大的問題可能是使用「父母」和「孩子」這兩個字。對於基類和派生類,這些都是非常可怕的*隱喻:用一般的說法,一個孩子通常不是父親,也不是父母的更具體的實例。一個更好的比喻是「基類」和「派生類」。 –

+0

修復了語法問題:) – Kam

回答

7

如果cH1方法在語義上適用於base,則使其成爲base的方法。 否則,請將cH1改爲derived,並使用dynamic_cast。 我認爲你的類的語義應該驅動你的選擇。

舉例來說,如果你有一個基類Vehicle和派生類CarMotorbike,並Aircraft,像TakeOff()的方法有Aircraft,但不兼容CarMotorbike,一個語義,所以你可能想使TakeOff()Aircraft方法,而不是Vehicle方法。

+0

我一直聽到這個詞,我從來沒有理解它:/ 你是什麼意思的「語義」適用於基地? – Kam

+2

@Kam:例如,如果您有一個基類'Vehicle'和派生類'Car','Motorbike'和'Aircraft',像TakeOff()這樣的方法具有與'Aircraft'兼容的語義,但不能與'汽車'或'摩托車',所以你可能想要'TakeOff()'飛機'的方法,而不是'車輛'的方法。 –

2

dynamic_cast更乾淨,更靈活,但速度稍慢。

請記住,當您使用dynamic_cast來檢查返回的NULL指針。

+0

'dynamic_cast'如何更乾淨和更靈活?在某些情況下'dynamic_cast'可能是合理的,但從所給出的信息來看,我認爲我們不能斷定這是其中之一。 (一般來說,虛函數的使用更清晰。) –

+0

@JamesKanze,如果父類沒有被與那個類無關的函數混淆,它會更乾淨。我同意我們需要更多關於類別細節的信息來真正知道。 –

3

首先,爲了使用dynamic_castbase必須至少有一個虛擬功能。

二,使用dynamic_cast通常是是設計錯誤的標誌。如果derived確實是base的子項,那麼derived對象應該能夠站在需要base對象的任何位置,這通常意味着base具有虛擬函數,不管是純虛擬還是非虛擬函數,並且derived將覆蓋部分或全部他們。

雖然不知道cH1是做什麼的,但是不可能推薦一種方法。

+0

這並不總是一個錯誤 - 有時候你需要一些有共同點但不是別人共同點的對象。 –

+0

對具體類使用'dynamic_cast'幾乎總是一個錯誤,但對於一個類(或一組類)來說,支持擴展接口並不罕見。在這種情況下,'dynamic_cast'是支持訪問擴展接口的一種方式。 –

+0

我已經強調**這個詞通常是**,因爲它似乎被忽略了。我沒有說這總是一個錯誤。 –