回覆列表
  • 1 # 娜塔莉庫珀

    虛擬函式的作用就是介面類能夠提供協議(即這個介面的功能是什麼,比如都是進行繪畫,相對來說比較抽象),而各個子類可以給出具體不同的實現(比如長方形繪畫時可以畫出長方形,而三角形則畫出來的就是三角形)。呼叫虛擬函式的客戶只需要知道虛擬函式的提供的協議,而不需要關心這個實現這個虛擬函式的到底是個什麼類(因為都是從一個基類繼承的)。

    當然你可能會想,為什麼不能用非虛擬函式做上面的事情,我們可以實現時指定一個型別,比如有一個成員用來標識形狀的型別,而在實現時用這個型別來判定如何進行繪畫,簡而言之就是if else或者switch語句,如同下面的程式碼:

    class shape { int type;public: void draw() { switch (type) { case rectangle: draw_rectangle(); break; case circle: draw_circle(); break; }};

    這個問題在於,當你有一個很多shape時,這個switch case將難以管理,因為有時候程式碼中有些地方就是需要根據型別來做判斷,但是此時你會傾向於使用switch case來實現這些程式碼。久而久之,一旦加個新型別時,就會很難維護,因為要改動很多地方,就容易出錯(當然如果改動地方不多,問題不會很大)。

    但是如果使用虛擬函式實現,那麼各個子類管理自己的實現,而有需要依據型別來判斷的地方,可以透過虛擬函式來實現,因為每個類可以定製這種行為,對於draw而言,可以

    class rectangle : public shape {public: virtual void draw() { // draw rectangle; }};class circle : public shape {public: virtual void draw() { // draw circle }};

    這樣當我們需要加新shape的時候,只需要新增一個新的子類,實現draw(或者其他依賴於型別的函式時),就不用到處去修改那些swtich case語句了,也不容易出錯了。

    敏捷開發一書中,提到的OCP(開放封閉原則),就可以用虛擬函式來做到。

  • 中秋節和大豐收的關聯?
  • 怎麼鑑定和田玉真假?