1. 程式人生 > 其它 >如何使用C語言的面向物件

如何使用C語言的面向物件

我們都知道,C++才是面向物件的語言,但是C語言是否能使用面向物件的功能?

(1)繼承性

1 typedef struct _parent
2 {
3 int data_parent;
4 }Parent;
5 typedef struct _Child
6 {
7 struct _parent parent;
8 int data_child;
9 }Child;

 在設計C語言繼承性的時候,我們需要做的就是把基礎資料放在繼承的結構的首位置即可。這樣,不管是資料的訪問、資料的強轉、資料的訪問都不會有什麼問題。

(2)封裝性

class的類成員預設情況下都是private,而struct的成員都是public(不能改變),所以如何讓C語言實現封裝的功能呢?答案就是函式指標;這在核心中得到了廣泛的應用;

1 struct _Data;
2 typedef  void (*process)(struct _Data* pData);
3 typedef struct _Data
4 {
5     int value;
6     process pProcess;
7 }Data;

   封裝性的意義在於,函式和資料是綁在一起的,資料和資料是綁在一起的。這樣,我們就可以通過簡單的一個結構指標訪問到所有的資料,遍歷所有的函式。封裝性,這是類擁有的屬性,當然也是資料結構體擁有的屬性。

(3)多型性

在C++中,多型通常都是使用虛擬函式來實現的,但是C語言中並沒有虛擬函式,如何實現過載呢?

答案也顯而易見,也是函式指標的擴充套件,以下面例子為例:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 //虛擬函式表結構
  5 struct base_vtbl
  6 {
  7     void(*dance)(void *);
  8     void(*jump)(void *);
  9 };
 10 
 11 //基類
 12 struct base
 13 {
 14     /*virtual table*/
 15     struct base_vtbl *vptr;
 16 };
 17 
 18 void base_dance(void *this)
 19 {
 20     printf("base dancen");
 21 }
 22 
 23 void base_jump(void *this)
 24 {
 25     printf("base jumpn");
 26 }
 27 
 28 /* global vtable for base */
 29 struct base_vtbl base_table =
 30 {
 31         base_dance,
 32         base_jump
 33 };
 34 
 35 //基類的建構函式
 36 struct base * new_base()
 37 {
 38     struct base *temp = (struct base *)malloc(sizeof(struct base));
 39     temp->vptr = &base_table;
 40     return temp;
 41 }
 42 
 43 
 44 //派生類
 45 struct derived1
 46 {
 47     struct base super;
 48     /*derived members */
 49     int high;
 50 };
 51 
 52 void derived1_dance(void * this)
 53 {
 54     /*implementation of derived1's dance function */
 55     printf("derived1 dancen");
 56 }
 57 
 58 void derived1_jump(void * this)
 59 {
 60     /*implementation of derived1's jump function */
 61     struct derived1* temp = (struct derived1 *)this;
 62     printf("derived1 jump:%dn", temp->high);
 63 }
 64 
 65 /*global vtable for derived1 */
 66 struct base_vtbl derived1_table =
 67 {
 68     (void(*)(void *))&derived1_dance,
 69     (void(*)(void *))&derived1_jump
 70 };
 71 
 72 //派生類的建構函式
 73 struct derived1 * new_derived1(int h)
 74 {
 75     struct derived1 * temp= (struct derived1 *)malloc(sizeof(struct derived1));
 76     temp->super.vptr = &derived1_table;
 77     temp->high = h;
 78     return temp;
 79 }
 80 
 81 
 82 
 83 int main(void)
 84 {
 85 
 86     struct base * bas = new_base();
 87     //這裡呼叫的是基類的成員函式
 88     bas->vptr->dance((void *)bas);
 89     bas->vptr->jump((void *)bas);
 90 
 91 
 92     struct derived1 * child = new_derived1(100);
 93     //基類指標指向派生類
 94     bas  = (struct base *)child;
 95 
 96     //這裡呼叫的其實是派生類的成員函式
 97     bas->vptr->dance((void *)bas);
 98     bas->vptr->jump((void *)bas);
 99     return 0;
100 }

 綜上所述,可以實現C語言的面向物件功能;