1. 程式人生 > >如何使用C語言的面向對象

如何使用C語言的面向對象

std 通過 基礎 truct a* tdi str virt public

我們都知道,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 dance\n"); 21 } 22 23 void base_jump(void *this) 24 { 25 printf("base jump\n"); 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 dance\n"); 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:%d\n", 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語言的面向對象功能;

如何使用C語言的面向對象