三月 4th, 2018

我们都知道,C++才是面向对象的语言,但是C语言是否能使用面向对象的功能?

(1)继承性

typedef struct _parent
{
int data_parent;
}Parent;
typedef struct _Child
{
struct _parent parent;
int data_child;
}Child;

在设计C语言继承性的时候,我们需要做的就是把基础数据放在继承的结构的首位置即可。这样,不管是数据的访问、数据的强转、数据的访问都不会有什么问题。

(2)封装性

class的类成员默认情况下都是private,而struct的成员都是public(不能改变),所以如何让C语言实现封装的功能呢?答案就是函数指针;这在内核中得到了广泛的应用;

struct _Data;
typedef  void (*process)(struct _Data* pData);
typedef struct _Data
{
int value;
process pProcess;
}Data;

封装性的意义在于,函数和数据是绑在一起的,数据和数据是绑在一起的。这样,我们就可以通过简单的一个结构指针访问到所有的数据,遍历所有的函数。封装性,这是类拥有的属性,当然也是数据结构体拥有的属性。

(3)多态性

在C++中,多态通常都是使用虚函数来实现的,但是C语言中并没有虚函数,如何实现重载呢?

答案也显而易见,也是函数指针的扩展,以下面例子为例:

#include <stdio.h>
#include <stdlib.h>

//虚函数表结构
struct base_vtbl
{
void(*dance)(void *);
void(*jump)(void *);
};

//基类
struct base
{
/*virtual table*/
struct base_vtbl *vptr;
};

void base_dance(void *this)
{
printf(“base dance\n”);
}

void base_jump(void *this)
{
printf(“base jump\n”);
}

/* global vtable for base */
struct base_vtbl base_table =
{
base_dance,
base_jump
};

//基类的构造函数
struct base * new_base()
{
struct base *temp = (struct base *)malloc(sizeof(struct base));
temp->vptr = &base_table;
return temp;
}
//派生类
struct derived1
{
struct base super;
/*derived members */
int high;
};

void derived1_dance(void * this)
{
/*implementation of derived1’s dance function */
printf(“derived1 dance\n”);
}

void derived1_jump(void * this)
{
/*implementation of derived1’s jump function */
struct derived1* temp = (struct derived1 *)this;
printf(“derived1 jump:%d\n”, temp->high);
}

/*global vtable for derived1 */
struct base_vtbl derived1_table =
{
(void(*)(void *))&derived1_dance,
(void(*)(void *))&derived1_jump
};

//派生类的构造函数
struct derived1 * new_derived1(int h)
{
struct derived1 * temp= (struct derived1 *)malloc(sizeof(struct derived1));
temp->super.vptr = &derived1_table;
temp->high = h;
return temp;
}

 

int main(void)
{

struct base * bas = new_base();
//这里调用的是基类的成员函数
bas->vptr->dance((void *)bas);
bas->vptr->jump((void *)bas);
struct derived1 * child = new_derived1(100);
//基类指针指向派生类
bas  = (struct base *)child;

//这里调用的其实是派生类的成员函数
bas->vptr->dance((void *)bas);
bas->vptr->jump((void *)bas);
return 0;
}

综上所述,可以实现C语言的面向对象功能;

Comments are closed.