如何使用C语言的面向对象
程序员文章站
2022-05-18 08:51:19
我们都知道,C++才是面向对象的语言,但是C语言是否能使用面向对象的功能? (1)继承性 在设计C语言继承性的时候,我们需要做的就是把基础数据放在继承的结构的首位置即可。这样,不管是数据的访问、数据的强转、数据的访问都不会有什么问题。 (2)封装性 class的类成员默认情况下都是private,而 ......
我们都知道,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语言的面向对象功能;