Skip to main content
OOP in C
 Inherit


           elpam.tw@gmail.com
           elpam@Taiwan, Taipei, 2008
LICENSE
●   本投影片授權方式為:
    –   姓名標示─非商業性─相同方式分享 3.0  台灣版
    –   http://creativecommons.org/licenses/by­nc­sa/3.0/tw/




●   所有的範例程式皆為 Public Domain




                              elpam.tw@gmail.com
About This Slides
●   All example was build by 
    –   GCC­4.1.3
    –   GLIB­1.2.10
    –   GMAKE­3.81




                      elpam.tw@gmail.com
C  Language Review
●   Stack
    –   Caller Function's Address
    –   CPU's Register
    –   Local Value
●   Heap (run­time heap)
    –   managed by malloc




                         elpam.tw@gmail.com
Address Space
●   Linux Memory Model
    –   copy from Jserv's               STACK
        Hacking Hello World




                                        HEAP




                        elpam.tw@gmail.com
Function Stack          Caller's Address
                                             Return Address


void Func_B()                                  Local Value
{
    int a,b;
   /* do nothing*/
}                                                               Low
void Func_A()                                  int b
{                       Func_B's Stack         int a
    char a;                                   Func_A
    Func_B();
}
                                               char a
                        Func_A's Stack
                                                main
int main()
{
    Func_A();
}                        main's stack            ....

                        elpam.tw@gmail.com                      High
After Review
●   請了解 Callee Stack 裡頭會放置那些東西
●   請了解 Callee Stack Release 後那些變數會被清
    除掉
●   請確定已正確的了解 Stack 與 Heap 的差別




                elpam.tw@gmail.com
Structure




elpam.tw@gmail.com
Structure (I)
                                      /* 1­1.c */
 ●   Address + Offset                 struct A{
                                         int a;
                                         int b;
     –   pa = 0x804a008               };
     –   pa ­> a == pa + 0            int main()
                                      {
     –   pa ­> b == pa + 4             struct A* pa =malloc(sizeof(struct A));

                                        printf("%x,%x,%xn"
                                                ,pa, &(pa­>a), &(pa­>b) );

                                        free( pa );
 #> ./1­1                             }
804a008,804a008,804a00c
 #>


                             elpam.tw@gmail.com
●   所有的東西都是 Memory Address
●   ­>  所代表的意義是 offset ,而這一個數值的大
    小可以在 Compiler Time 被決定




               elpam.tw@gmail.com
Structure (II)
                                      /* 1­2.c */
                                      struct A{                       Size = 8 byte
 ●   pa == pb                            int a;   int b;
                                      };
      –     pa ­> c Compile Error     struct B{
                                         int a;   int b;
      –     pb ­> c Correct              int c;                       Size = 12 byte
                                      };
                                      int main()
                                      {
                                       struct A* pa =malloc(sizeof(B));
                                       struct B* pb = pa;
                                        pa ­> a = 1;     pa ­> b = 2;
 #> ./1­2                               pb ­> c = 3;
1,2,3
  #>                                    printf("pb(%d,%d,%d)n"
                                                       ,pb­>a,pb­>b,pb­>c );
                                      }


                              elpam.tw@gmail.com
●   Pointer 的 Type 與被 allocate 的記憶體大小是沒
    有關係的
●   請注意我們是如何使用 casting




                 elpam.tw@gmail.com
/* 1­3.c */
                  Structure (III)
struct A{
     int a;
●
}; Casting        int main()
                  {
                       struct A* pa = malloc( sizeof(struct A) );
struct B{              struct B* pb = pa;
    short b;           struct C* pc = pa;
    short c;
};                    pc ­> hi_b = 0x12;
                      pc ­> low_b = 0x34;
struct C{             pc ­> hi_c = 0x56;
    char low_b;       pc ­> low_c = 0x78;
    char hi_b;
    char low_c;       printf("pb­>b(0x%x)  pb­>c(0x%x)n",pb­>b,pb­>c );
    char hi_c;        printf("pa­>a(0x%x)n",pa­>a );
};
                      free( pa );
                  }


                        elpam.tw@gmail.com
Structure (III) (cont')
●   Memory Casting
●   x86 is little­endian                    pc ­> hi_b = 0x12;
                                            pc ­> low_b = 0x34;
                                            pc ­> hi_c = 0x56;
                                            pc ­> low_c = 0x78;




                                        #>./1­3
                                      pb­>b(0x1234)  pb­>c(0x5678)
                                      pa­>a(0x56781234)
                                        #>




                       elpam.tw@gmail.com
Inherit




elpam.tw@gmail.com
C++ Review
                                      /* 1­6.cpp */
                                      class A{
●   Casting to Parent                    public:
                                            int a;
                                      };
                                      class B : public A{
                                         public:
                                            int b;
                                      };

                                      int main()
                                      {
                                           B b;
                                           b . b  = 2;
                                           A(b) . a = 1
                                      }




                        elpam.tw@gmail.com
Inherit
                                          int main()
                                          {
   ●   sizeof(A) =  8                      struct B* pb = malloc(sizeof(struct B));
                                            pb ­> parent . a = 0;
   ●   sizeof(B) = 12                       pb ­> parent . b = 1;
                                            pb ­> c = 2
                    /* 1­4.h */           }
                    struct A{
                       int a;
                       int b;             /* 1­4.c */
       Inherit A    };                    int main()
                    struct B{             {
                       struct A parent;    struct A* pa =malloc(sizeof(struct B));
                       int c;              struct B* pb = pa;
                    };                      pa ­> a = 0;
                                            pa ­> b = 1;
  #>./1­4                                   pb ­> c = 2;
pa(1,2) pb(3)                             }
  #>
                             elpam.tw@gmail.com
Inherit & Casting
                                         /* 1­5.c */
   ●   Casting to Parent                 int main()
                                         {
                                          struct B* pb =malloc(sizeof(struct B));
                                           pb ­> c = 3;
                                          struct A* pa = pb;
                   /* 1­5.h */             pa ­> a = 1;
                   struct A{               pa ­> a = 2;
                      int a;
                      int b;               printf("pa(%d,%d) pb(%d)n"
                   };                              ,pa­>a,pa­>b,pb­>c );
                   struct B{             }
                      struct A parent;
                      int c;  
                   };

  #>./1­5
pa(1,2) pb(3)
  #>
                            elpam.tw@gmail.com
Public Member Value in C++
                                      int main()
                                      {
class A{
                                        B* b = new B;
public:
   int a;
                                        b . a = 0;
   int b;
                                        b . b = 1;
};
                                        b . c = 2;
class B : public A {
                                      }
public:
   int c;  
};
                                      int main()
                                      {
                                        A* a = new b;

                                        a . a = 0;
                                        a . b = 1;
                                        a . c = 2;       /* error */
                                        B(a) . c = 2;  /* correct */
                                      }
                       elpam.tw@gmail.com
Object Inherit
●   C Language                           ●   C++


     struct A{                                     class A{
        int a;                                     public:
        int b;                                        int a;
     };                                               int b;
     struct B{                                     };
        struct A parent;                           class B : public A {
        int c;                                     public:
     };                                               int c;  
                                                   };




                              elpam.tw@gmail.com
Type Casting ( 形態轉換 )
●   C Language                         ●   C++
    –   Structure­to­Structure             –     dynamic_cast
         ●   Address­to­Address            –     static_cast
                                           –     reinterpret_cast
                                           –     const_cast




                            elpam.tw@gmail.com
Inherit in C
●   C ­> B ­> A
                                       /* error memory access */
                                       int main()
    struct A{                          {
       int v1;                          struct B* pb = malloc(sizeof(B));
       int v2;                          struct C* pc = pb; /* correct */
    };                                  pc ­> v1 = 0; /* run time error */
    struct B{
       struct A parent;                }
       int v1;  
    };
    struct C{
       struct B parent;                struct C c;
       int v1;                         struct B* pb = &c;  /* use B's member */
    };                                 struct A* pb = &c;  /* use A's member */

                            elpam.tw@gmail.com
Conclusion 



我們可以使用 memory casting
的技巧來描述繼承關係

*  因為缺乏語法 (Compiler) 的保護,所以我們必須
要小心的使用



            elpam.tw@gmail.com
Questions
●   建構子 (Constructor)  還有需要嗎 ?
●   但 C++ 的繼承還提供了 Virtual Function,  需要
    這樣的功能嗎 ?  該如何實作 ?
    –   下一個投影片將討論這兩個問題




                 elpam.tw@gmail.com