Fork me on GitHub

如何使用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 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语言的面向对象功能;

 

posted @ 2018-02-14 11:31  yooooooo  阅读(2086)  评论(4编辑  收藏  举报