1 / 17

C 語言實做 C++ 物件導向特性

C 語言實做 C++ 物件導向特性. 封裝繼承與多型. C 也可以很 OO(Object Oriented). 善用 struct 語法對應與命 名規則 瞭解 C++ 在背後幫我們做了哪些事. 善用 Struct. 一個資料結構必定有多個操作的演算法 ( 反之不一定 ) 這個演算法正是對於資料結構的操作方法 (Method/Manipulation) 在一個二元搜尋樹尋找一個 key ,尋找的演算法就是二元搜尋樹的一種操作。 我們把水放入杯子,杯子是一個資料結構,具有儲存水的演算法。. 語法對應與命名規則.

Download Presentation

C 語言實做 C++ 物件導向特性

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. C語言實做C++物件導向特性 封裝繼承與多型

  2. C也可以很OO(Object Oriented) • 善用struct • 語法對應與命名規則 • 瞭解C++在背後幫我們做了哪些事

  3. 善用Struct • 一個資料結構必定有多個操作的演算法(反之不一定) • 這個演算法正是對於資料結構的操作方法(Method/Manipulation) • 在一個二元搜尋樹尋找一個key,尋找的演算法就是二元搜尋樹的一種操作。 • 我們把水放入杯子,杯子是一個資料結構,具有儲存水的演算法。

  4. 語法對應與命名規則 • C沒有Reference,所有的Reference都要成為指標,指標仍然是指標。 • 沒有運算子多載,必須以全名表達。 • 比如索引運算子以indexOf或者index_of • C++ Method是一種針對物件的操作,Compiler偷偷塞了this指標。 • 我們要讓function第一個參數為this • int& Class::getData(int value); • int* class_get_data(Class* pthis,int value); • int& Class::getData(int value) const; • int* class_get_data(const Class* pthis,int value);

  5. 語法對應與命名規則 ( cont. ) • 所有的命名規則來自於對於資料結構操作方法的描述: • Class的GetData • C++: Class::getData • C++以小寫開頭,之後每個單字為大寫開頭 • C: class_get_data() • C以小寫描述資料結構名稱,再以底線分隔單字

  6. 語法對應與命名規則 ( cont. ) • 從範例看到 • C++保證不會更改到this的函式 • int& Class::getData(int idx) const; • 轉為C之後即是將this指標設為const • int* class_get_data(const Class* pthis,int idx);

  7. 以C實做繼承以及多型 • C++具有物件導向程式語言的威力,封裝繼承與多型 • C語言實做封裝容易,只要將method傳this以及更改命名方式即可。

  8. 以C實做繼承以及多型 (cont.) • 進行繼承,我們要瞭解到: • 每一次的繼承都會保留父代的資料,因此子代會越來越大。 • 父代函式可以叫用再子代的物件。 • 父代的可複寫函式是透過Virtual Table管理的。 • 建構子與解構子順序。 • 解構子是複寫的。

  9. 以C實做繼承以及多型 (cont.) • 首先來看前兩點 • 每一次的繼承都會保留父代的資料,因此子代會越來越大。 • 父代函式可以叫用再子代的物件。 • 我們可以想像第二點會是第一點的延伸。 • 父代函式作用再子代,是來自於子代有一份父代Class的資料。

  10. 以C實做繼承以及多型 (cont.) 再C語言可以藉由簡單的data link(data layout)方式,讓父代盡可能擺在第一個位置。 typedef struct SuperClass{ int data; int someArray[ 16 ]; }SuperClass; typedef struct ChildClass{ SuperClass super; int dataOfChild; }ChildClass;

  11. 以C實做繼承以及多型 (cont.) • 接著看以下的敘述 • 父代的可複寫函式是透過Virtual Table管理的。 • 建構子與解構子順序。 • 解構子是複寫的。 • 關於Virtual Table,我們知道他被稱為Dynamic Binding,執行期決定function為何。 • 恰好function pointer為一種可以被當作函式叫用,且可以執行期間改變的pointer。

  12. 以C實做繼承以及多型 (cont.) • Function pointer群的管理,我們可以將所有的function pointer放一份到Super Class • 缺點: • 每次複寫需要改變很多指標 • 每個子代物件都有同樣的一大堆指標,且內容重複。

  13. 以C實做繼承以及多型 (cont.) • 經由所有相同Class的物件的Function Pointer都是重複這點看來 • 再該代版本只有一個。 • 他被稱為virtual table • 因此可以想見那確實是一個表格,一個靜態存在的表格。

  14. 以C實做繼承以及多型 (cont.) • 我們可以想像他大概長這樣 typedef struct SuperClassVirtualTable { void (*superMethod)(Super*); void (*superFinal)(Super*) } SuperClassVirtualTable; • 在程式定義區域應該會有一些實做的Function,實做過後會有一個靜態實體指向這些Function,也就是: static void super_method_virtual(Super* s){} static void super_final_virtual(Super* s) {} SuperClassVirtualTable superVirtualTable = { super_method_virtual, super_final_virtual };

  15. 以C實做繼承以及多型 (cont.) • 既然一個Class只有一份,那麼Class中就不需要存有多個pointer • 只需要一個指向Class的函式表指標即可。 typedef struct SuperClass{ int data; int someArray[ 16 ]; void* virtualTable; }SuperClass;

  16. 以C實做繼承以及多型 (cont.) • 為了達成父代函式未被複寫的版本仍為原先的版本,設定virtual table的工作應該包含在init函式。 • 如何叫用複寫函式? • 透過virtualTable • ((SuperClassVirtualTable*)this->virtualTable)->superMethod(this); • 由於函式表將來會被覆寫,因此父代的函式可以透過函式表找到子代覆寫的版本。 • 達成多型效果。

  17. 以C實做繼承以及多型 (cont.) • 建構子順序 • 父代建構後才建構子代 • 在子代的init必須先叫用父代的init • 解構子順序 • 子代解構後才解構父代 • 在子代的final先處理自己的資料 • 之後再執行父代final

More Related