1 / 20

Virtual Function

Virtual Function. Jing( 井民全). Virtual Function 基本概念. 基礎類別定義基本的功能 衍生類別 繼承了基礎類別 定義特殊的功能. class Animal. weight eat() SetWeight(). 動物的基本功能. class Cat. eat() SetWeight() Sleep(). 貓的功能. Virtual Function 基本概念. class Animal { public: int weight; void eat(); void setWeight();

Download Presentation

Virtual Function

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Virtual Function Jing(井民全)

  2. Virtual Function基本概念 • 基礎類別定義基本的功能 • 衍生類別 • 繼承了基礎類別 • 定義特殊的功能 class Animal weight eat() SetWeight() 動物的基本功能 class Cat eat() SetWeight() Sleep() 貓的功能

  3. Virtual Function基本概念 class Animal { public: int weight; void eat(); void setWeight(); }; class Animal weight eat() SetWeight() 動物的基本功能 class Cat:public Animal { public: void eat(); void setWeight(); void Sleep(); }; class Cat eat() SetWeight() Sleep() 貓的功能

  4. Cat *Mycat=new Cat(); Mycat->eat(); Virtual Function基本概念 • 貓有貓的吃飯方式! class Animal weight eat() SetWeight() 動物的基本功能 class Cat eat() SetWeight() Sleep() 貓的功能

  5. class Animal weight eat() SetWeight() 動物的基本功能 ? class Cat eat() SetWeight() Sleep() 貓的功能 Virtual Function基本概念 • 因為貓是動物的一種, 所以我們可以用動物reference貓 Polymorphism(多形) Cat *Mycat=new Cat(); Animal *obj=Mycat; obj->eat();

  6. class Animal Cat *Mycat=new Cat(); Animal *obj=Mycat; weight eat() virtual SetWeight() 動物的基本功能 obj->eat(); class Cat eat() SetWeight() Sleep() 貓的功能 Virtual Function基本概念 • 呼叫貓的eat(): 加入 virtual 關鍵字 virtual 範例程式: virtualConcept1.cpp

  7. 透過 Animal 只要是Animal型別就可以操作 • 可以視為 Animal 型態操作,又可呼叫自己特別function. • 泛型處理 Animal 存取未知物件 的相對應的 function

  8. 插頭必須是三孔 電壓一定要符合 220V 介面的概念 • 建立一個功能 • 只接受某種型態的物件 • 某些電器需要的是三孔插座,某些電器需要的是220V的電壓 電力公司服務 我是三孔插座 我是220V 電器1 電器2

  9. 介面的概念 • 接受電力公司提供服務的條件 • 擁有三孔插座 • 可接受 220V 電壓 若想接受服務, 則電器(物件)必須符合條件!! 3孔介面 120V電視機 220V介面

  10. class Plug3{ virtual public void Input3() =0; } class Volate220V{ virtual public void Input220V() =0; } class TV:public Plug3,public Volate220{ public: void input3(){ } void input220V(){ } }; 把3孔轉2孔的轉換程式放在這 把220轉120V電壓轉換程式放在這 3孔介面 120V電視機 220V介面

  11. class Sortable class Person 假設 Person 繼承 Sortable 範例程式: VirtualDestructor.dsw 虛擬解構式 Sortable *sp; Person *pp=new Person("Frank","frank@icce.rug.nl","363 3688"); // 使用基礎類別指標 reference Person sp=pp;     請問下面的程式碼,會呼叫 Sortable 還是 Person 的解構子? delete sp; <解答> 若不加入 virtual在sp的解構式中,則 delete sp 會呼叫 sp的解構子,而非 Person的解構子

  12. 虛擬解構式 • C++ 允許 解構式虛擬化, 以確定呼叫正確的解構式 所以應該在基礎類別 Sortable 的解構式中加入 virtual. class Sortable{ // < 其他程式碼 > virtual ~Sortable( ){ } } 如此 delete sp; 才會呼叫正確的 Person的解構式

  13. class Sortable class Person 2. 執行Sortable的解構子 問題: Delete Derived 會呼叫 Derived虛擬解構式,但是程式會繼續呼叫 Base 的解構式嗎? 我們知道在 Sortable 的解構子加上 virtual後, 執行delete sp; 會呼叫目前指向物件的解構子 Sortable *sp; Person *pp=new Person("Frank","frank@icce.rug.nl","363 3688"); // 使用基礎類別指標 reference Person sp=pp;     delete sp; 1. 執行Person 的解構子 解構的順序為 ~Derived() -> ~Base()

  14. 問題: 注意: 這裡重複繼承了 Base void main( ) { Derived obj; obj.getfield(); } 呼叫哪一個 Base 的 getfield( ) 多重繼承下的虛擬函式 • 一個衍生類別可能繼承多個基礎類別 考慮下面的 code class Base{   public: void setfield(int val){ field = val; }        int getfield() const   { return (field); }   private:int  field; }; class Derived: public Base, public Base{  };

  15. 重複繼承了 Vechicle 佔用了兩份空間 多重繼承下的虛擬函式 • 程式很大的時候,則會亦有類似狀況(因為基礎類別可能不是你寫的) • 多重繼承推導圖與內部結構圖

  16. 完整程式範例: VirtualDerived.dsw 解決方法: 虛擬繼承Virtual Base classes • 對於一個 AirAuto, 我們只須要一個 weight. class Land: virtual public Vehicle{ ...}; class Air: virtual public Vehicle{ ...}; 虛擬繼承與虛擬函數不同的地方在於 虛擬繼承完全可以在 compile-time 解析

  17. 執行時期的形態辨別 class 動物 • 一個基礎類別的指標,可能指的是衍生類別. • 那麼我們在執行的時候, 要如何知道這個基礎類別指標到底是指向哪一個物件? 動物 *p=new 貓; class 貓 重要觀念: 貓是動物的一種. 所以我們可以用動物存取貓. Why? 使得任何的動物種類的物件 都可以用 p 存取. 這就是抽象化,

  18. C++ 的解決方案 • typeid指出目前的指標到底是那一種型態. (傳回字串告訴你) • dynamic_cast運算子來將一個指標轉換成 基礎類別型態 或 衍生類別型態. 在VC中,必須設定才允許使用 dynamic_cast. [project]->[setting...]->[C++]->[C++ Language]: Enable Run-Time Type Information(RTTI)

  19. typeid 範例1 必須先 #include <typeinfo> 在class 中至少要有一個 virtual function 考慮下面的code #include <typeinfo> void main(){ cout << typeid(12).name() << endl; cout << typeid(3.14).name() << endl; } 會印出 int 會印出 double 看 typeid範例2.doc

  20. dynamic_cast 範例 See dynamic_cast.doc

More Related