我們都知道,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 }