面向对象的思想,不应受某种语言的限制,面向过程的C语言同样如此。C里面没有类,可以用结构体;没有类的方法,可以使用函数指针;
最重要的,没有继承的概念,怎么解决呢?
想想强制类型转换,为什么能转换成功呢?这就为实现继承做了基础,加上前面有几篇写过可执行文件的结构,将在后面给出一种方式。
1.一个简单的类
#include<stdio.h>
#include<stdlib.h>
typedef struct Man {
int age;
void (*sayHi)();
}Man;
void manSayHi(){
printf("hi ... \n");
}
Man* createMan(){
return (Man*)malloc(sizeof(Man));
}
void deleteMan(Man* m){
free(m);
}
Man* initMan(Man* m,int age){
m->age = age;
m->sayHi = manSayHi;
return m;
}
int main(){
int a;
Man* m = initMan(createMan(),30);
m->sayHi();
printf("man age = %d \n",m->age);
deleteMan(m);
//这里只是让弹出的命令窗口,等待一个数值,不消失。
scanf_s("%d",&a);
}
在结构体Man中,age相当于一个成员变量,sayHi是一个函数指针,相当于一个成员方法。
有一点需要说明,在createMan函数中,malloc函数返回的是一个void* 的指针,在这里强制类型转换成了一个 Man* 的指针,这是在VS2012 中。
在Mac下Xcode中不需要强转。
C语言中,void* 本身可以指向任意类型的指针,VS的语法检查是否过于严格了呢。
对一个类来讲,有构造 和 析构 两部,我们这里对应的构造是分成了两步:
①分配内存 createMan
②初始化 initMan
析构只有一步:
释放内存deleteMan
运行结果:
2.类的继承
提到类的继承,想想父类与子类的关系,子类可以向父类转型,这一点跟强制类型转换是否很相似?
那么只要在链接成的可执行文件中,将子类与父类的内容按顺序排放,就实现了一个继承的关系。
#include<stdio.h>
#include<stdlib.h>
#define Obj_Field void (*onDestroy)();
#define createObj(Type) malloc(sizeof(Type))
#define deleteObj(Type)\
{\
Type->onDestroy();\
free(Type);\
}
typedef struct Object{
Obj_Field
}Object;
Object* initObj(void* obj){
printf("obj init ... \n");
}
typedef struct Man {
Obj_Field
int age;
void (*sayHi)();
}Man;
void manSayHi(){
printf("hi ... \n");
}
void manOnDestroy(){
printf("man on destroy ... \n");
}
Man* initMan(Man* m,int age){
m->age = age;
m->sayHi = manSayHi;
m->onDestroy = manOnDestroy;
printf("man init ... \n");
return m;
}
int main(){
int a;
Man* m = initMan((Man*)createObj(Man),30);
m->sayHi();
printf("man age = %d \n",m->age);
deleteObj(m);
scanf_s("%d",&a);
}
先看运行结果:
在这里只要把 Obj_Field 这个宏放在 Man的最开始的位置上,就可以实现 继承的关系了,即使向 Object转型,也不会因截断而出错。
这是声明Obj_Field 这个宏的原因。
创建对象也用了一个宏,是为什么呢?
因为一个子类所占用的空间往往比父类的要大,所以要动态的为子类非配空间,具体的类型还未确定。
需要等到真正执行程序的时候才去决定。
那么销毁对象的方式也就与此想通了。
这里依然如此,malloc分配返回的void* 要强转成具体类型。(Windows VS2012下,Mac Xcode不需要)
Man* m = initMan((Man*)createObj(Man),30);
这样,一个简单的继承就实现了。
来源:oschina
链接:https://my.oschina.net/u/1428119/blog/312781