事件
最近跟中二中的智仁學弟重構布丁學弟的Puddings_Dragon,
就是個勇者鬥惡龍的c++遊戲,
以前就覺得應該是很多if else的小遊戲吧! 結果看完程式碼…
還真的是一大堆的if else,到底哪裡來的耐心寫出來的XD
最近寫到skill的部份,用Fire、Hide等繼承skill父類別,
然而呼叫子類別的use()時竟然只能呼叫父類別的use(),
求助PTT C_AND_CPP版後找到關鍵字 Virtual Function。
寫太久php,只記得C++沒有abstract、interface,完全忘記有virtual。
原code
Skill是父類別,規範子類別需有use()
Fire繼承Skill,Override覆寫 use()
class Skill
{
public:
void use(){...A...}
}
class Fire : public Skill
{
public:
void use(){...B...}
}
我用一個新的類別Skill_List將擁有的skill串起來方便程式使用
class Skill_List()
{
public:
Skill_List(){
this->skill[0]=new Fire;
this->skill[1]=new Hide;
}
private:
Skill *skill[2]
}
然而欲使用skill[0]的use()時,
執行的卻不是子類別Fire裡的use() B動作,而是父類別的A動作
我很困惑的是我儲存的列表明明是用指標存,但是為什麼會出現不屬於Fire類別的動作
Skill_List list;
list.skill[0]->use();
Virtual Function
Virtual Function可以實現「執行時期」的多型支援,是一個「晚期繫結」(Late binding)、「動態繫結」(Dynamicbinding)
反之,Overloading在編譯時期就決定,
是「早期繫 結」(Early binding)、「靜態繫結」(Static binding)
事件出事點
先了解以下code是可行的
//Fire 繼承 Skill
Skill *sptr;
Fire f;
sptr = &f;
然而sptr被宣告為Skill類別,因此只能存取Skill的成員方法,
這就是原code中最後list.skill[0]->use()
只能使用父類別成員方法的原因。
所以?
Virtual finction是在父類別就用virtual宣告,到了子類別再重新定義。
而父類別指標變不能使用virtual宣告的成員方法,
便可以子類別中的Virtual finction。
該目的是將操作決議延遲到執行時期才決定。
因此這在實現設計模式中工廠模式的工廠和產品時可以使用到,
將factory & product的成員方法宣告為virtual,
到了各產品定義時才定義成員方法的內容。