我有一個父類「基」和另一個繼承自「基」的類「派生」。dynamic_cast vs暴露父類中的虛函數(C++)
「派生」有1個方法cH1。
如果我這樣做:
base* b = new derived();
而且我希望能夠做到這一點:
b->cH1();
很明顯,我不能和有2個解決方案:
- 將基地中的cH1聲明爲純虛擬。
或做到這一點:
dynamic_cast<derived*>(b)->cH1();
哪一個是一個更好的做法?
我有一個父類「基」和另一個繼承自「基」的類「派生」。dynamic_cast vs暴露父類中的虛函數(C++)
「派生」有1個方法cH1。
如果我這樣做:
base* b = new derived();
而且我希望能夠做到這一點:
b->cH1();
很明顯,我不能和有2個解決方案:
或做到這一點:
dynamic_cast<derived*>(b)->cH1();
哪一個是一個更好的做法?
如果cH1
方法在語義上適用於base
,則使其成爲base
的方法。 否則,請將cH1
改爲derived
,並使用dynamic_cast
。 我認爲你的類的語義應該驅動你的選擇。
舉例來說,如果你有一個基類Vehicle
和派生類Car
,Motorbike
,並Aircraft
,像TakeOff()
的方法有Aircraft
,但不兼容Car
或Motorbike
,一個語義,所以你可能想使TakeOff()
的Aircraft
方法,而不是Vehicle
方法。
我一直聽到這個詞,我從來沒有理解它:/ 你是什麼意思的「語義」適用於基地? – Kam
@Kam:例如,如果您有一個基類'Vehicle'和派生類'Car','Motorbike'和'Aircraft',像TakeOff()這樣的方法具有與'Aircraft'兼容的語義,但不能與'汽車'或'摩托車',所以你可能想要'TakeOff()'飛機'的方法,而不是'車輛'的方法。 –
dynamic_cast
更乾淨,更靈活,但速度稍慢。
請記住,當您使用dynamic_cast
來檢查返回的NULL指針。
'dynamic_cast'如何更乾淨和更靈活?在某些情況下'dynamic_cast'可能是合理的,但從所給出的信息來看,我認爲我們不能斷定這是其中之一。 (一般來說,虛函數的使用更清晰。) –
@JamesKanze,如果父類沒有被與那個類無關的函數混淆,它會更乾淨。我同意我們需要更多關於類別細節的信息來真正知道。 –
首先,爲了使用dynamic_cast
,base
必須至少有一個虛擬功能。
二,使用dynamic_cast
是通常是是設計錯誤的標誌。如果derived
確實是base
的子項,那麼derived
對象應該能夠站在需要base
對象的任何位置,這通常意味着base
具有虛擬函數,不管是純虛擬還是非虛擬函數,並且derived
將覆蓋部分或全部他們。
雖然不知道cH1
是做什麼的,但是不可能推薦一種方法。
這並不總是一個錯誤 - 有時候你需要一些有共同點但不是別人共同點的對象。 –
對具體類使用'dynamic_cast'幾乎總是一個錯誤,但對於一個類(或一組類)來說,支持擴展接口並不罕見。在這種情況下,'dynamic_cast'是支持訪問擴展接口的一種方式。 –
我已經強調**這個詞通常是**,因爲它似乎被忽略了。我沒有說這總是一個錯誤。 –
請關掉你的大寫鎖定鍵; 'PARENT'表明這個名字是一個宏; '父母'是通常的用法。 –
我想說,你頭上最大的問題可能是使用「父母」和「孩子」這兩個字。對於基類和派生類,這些都是非常可怕的*隱喻:用一般的說法,一個孩子通常不是父親,也不是父母的更具體的實例。一個更好的比喻是「基類」和「派生類」。 –
修復了語法問題:) – Kam