Successfully reported this slideshow.
Your SlideShare is downloading. ×

OOP in C - Virtual Function (Chinese Version)

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Upcoming SlideShare
Gobject - Inherit (Chinese)
Gobject - Inherit (Chinese)
Loading in …3
×

Check these out next

1 of 19 Ad

More Related Content

Slideshows for you (20)

Advertisement

Similar to OOP in C - Virtual Function (Chinese Version) (20)

OOP in C - Virtual Function (Chinese Version)

  1. 1. OOP in C Virtual Function elpam.tw@gmail.com elpam@Taiwan, Taipei, 2008
  2. 2. LICENSE ● 本投影片授權方式為: – 姓名標示─非商業性─相同方式分享 3.0  台灣版 – http://creativecommons.org/licenses/by­nc­sa/3.0/tw/ ● 所有的範例程式皆為 Public Domain     elpam.tw@gmail.com
  3. 3. About This Slides ● All example was build by  – GCC­4.1.3 – GLIB­1.2.10 – GMAKE­3.81     elpam.tw@gmail.com
  4. 4. 請先覆習一下 Function Pointer 的使用方式     elpam.tw@gmail.com
  5. 5. Function Pointer /* 2­1.c */ typedef void (*FP) ( void ); void hello() { printf("hello "); } int main() { void world() { printf("worldn"); }   #> ./2­1 FP fp = hello;  hello world  fp();   #> fp = world; fp(); };     elpam.tw@gmail.com
  6. 6. Function Pointer (cont') /* 2­2.c */ ● 也可以當參數使用 typedef void (*FP) ( void ); #define ERROR 1 void error_test( FP callback ) { if( ERROR ){ callback(); } }   #> ./2­2 int main()   error happened  {   #> void error() { printf("error happenedn"); }        error_test( error ); };     elpam.tw@gmail.com
  7. 7. Function Pointer & Structure /* 2­3.c */ typedef void (*FP) ( void* ); ● 以 Function Pointer  struct A{         int a;               int b; 的方式實作 Member          FP  method; }; Function void a_real_method( void* p) {         struct A* this = p;         printf("%d,%dn",this­>a,this­>b); } int main() {   #> ./2­3         struct A a;   1,2         a.a = 1;        a.b = 2;   #>         a.method  = a_real_method;         a.method ( &a ); };     elpam.tw@gmail.com
  8. 8. Using Previous Slide to Implement Inherit 2­4.c ● 方便閱讀,加上一點 ' 命名規則 ' – 其實是龜毛的 Rule ● PREFIX_init – 該物件的 建構子 (Constructor) ● PREFIX_method – 該物件的 成員函式 (member function)     elpam.tw@gmail.com
  9. 9. Member Function's Inherit (1) struct A { void A_real_method_a( void* p) { int a; struct A* this = p; FP  method_a; printf("this is method_a %dn",this­>a);  }; } struct B { void B_real_method_b( void* p) { struct A parent; struct B* this = p; int b; printf("this is method_b %dn",this­>b);  FP  method_b; } }; int main()  { void a_init( struct A* a)  { struct B b; a ­> a = 1; a_init( &b );    a ­> method_a = A_real_method_a;        b_init( &b ); } void b_init( struct B* b)  { struct A* ap = &b; b ­> b = 2; b ­> method_b = B_real_method_b; ap ­> method_a( ap ); } b  .  method_b( &b ); };     elpam.tw@gmail.com
  10. 10. Member Function's Inherit (2) /* 2­4.c */ int main() ● Child 如果希望執行 ( 存取 )  { struct B b; Parent 的函式 ( 變數 ) ,需要 a_init( &b );    先 Cast 成 Parent 再執行 ( 存        b_init( &b ); 取) struct A* ap = &b; ap ­> method_a( ap ); b  .  method_b( &b ); };   #> ./2­4   this is method_a 1   this is method_b 2       #> elpam.tw@gmail.com
  11. 11. 結論 ● 我們可以實作 class_init() 時將 class 內的 member value and member function 都設定好 – 也就是 ''Constructor''  ● 自已實作 C 不提供的 Member Function!!     elpam.tw@gmail.com
  12. 12. Implement Virtual Function 2­5.c ● Child 的 init 可以將 Parent 的 Member Function 做改寫的動作,以達到 Virtual Function 的效果 – 下一頁粉紅色的那一行     elpam.tw@gmail.com
  13. 13. Virtual Function (1) void A_real_method_a( void* p)  { struct A* this = p; printf("this is %s %dn"                          ,__FUNCTION__,this­>a);  void A_init( struct A* a) } { void B_real_method_a( void* p)  a ­> a = 1; { a ­> method_a = A_real_method_a; struct B* this = p; } printf("this is %s %dn"                           ,__FUNCTION__,this­>b);  } void B_init( struct B* b) void B_real_method_b( void* p)  { { struct A* a = b; struct B* this = p; b ­> b = 2; printf("this is %s %dn" a ­> method_a = B_real_method_a;                            ,__FUNCTION__,this­>b);  b ­> method_b = B_real_method_b; } }     elpam.tw@gmail.com
  14. 14. Virtual Function (2) ● A_init 一定要比 B_init 先執行 – Parent 的 Constructor 需要先執 行 /* 2­5.c */ int main() { struct B b;   #> ./2­5 A_init( &b ); this is A_real_method_a 1 this is B_real_method_a 2 struct A* ap = &b; this is B_real_method_b 2 ap ­> method_a( ap );   #> B_init( &b ); ap ­> method_a( ap ); b  .  method_b( &b ); };     elpam.tw@gmail.com
  15. 15. Constructor's Wrapper 2­6.c     elpam.tw@gmail.com
  16. 16. Constructor in C (1) ● we use PREFIX_new to replace malloc – 所有的物件都以 PREFIX_NEW 產生,以確保 Constructor 被正確的執行 struct A{ struct A* A_new()    int a; {    int b;    struct A* ret = malloc( sizeof(A) ); };    ret ­> a = 0;    ret ­> b = 1;    return ret; }     elpam.tw@gmail.com
  17. 17. Constructor in C (2) ● 以前面的例子 /* 2­6.c */ /* 2­6.c */ int main() struct B* B_new() { {         struct B* pb = B_new();    struct B* pb = malloc( sizeof(B) );    struct A* pa = pb;         ((struct A*)pb) ­> method_a( pb );    A_init( pa );         pb ­> method_b( pb );    B_init( pb );    return pb; }; }     elpam.tw@gmail.com
  18. 18. Constructor in C (3) ● 繼承關係越復雜時, PREFIX_new 很難去維護 – 請試想三層繼承時,開發者希望在第一及第二層之間 再加上一層物件 ● 所以我們需要更有效率的方式來撰寫 Constructor – GObject 提供了一個有效率的方式     elpam.tw@gmail.com
  19. 19. Conclusion ● 以上的 Tips 提供了一種方式來撰寫 Object­ Oriented 的程式 – 可自行練習 :) ● 相較於 C++ 的繼承,此種方式所撰寫出來的物 件為靜態形別,所有的 Offset 都是 Compiler  Time 已決定好的,所以不會有繼承濫用的問題 – 執行效率 ● 但是如果不正確的使用,依舊會造成程式碼難以   閱讀,也容易產生 BUG  elpam.tw@gmail.com

×