我们都知道,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
#include
//虚拟函式表结构
struct base_vtbl
{
void(*dance)(void *);
void(*jump)(void *);
};
//基类
struct base
{
/*virtual table*/
struct base_vtbl *vptr;
};
void base_dance(void *this)
{
printf(“base dancen”);
}
void base_jump(void *this)
{
printf(“base jumpn”);
}
/* 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 dancen”);
}
void derived1_jump(void * this)
{
/*implementation of derived1’s jump function */
struct derived1* temp = (struct derived1 *)this;
printf(“derived1 jump:%dn”, 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 语言的物件导向功能;