Javascript多线程引擎(四)

Javascript多线程引擎(四)--之C语言单继承

 

  因为使用C语言做为开发语言, 而C语言在类的支持方面几乎为零, 而Javascript语言的Object类型是一个非常明显的类支持对象,所以这里需要提出一个方案对Object类型的继承进行支持.

  本章节介绍一个简单的基于C语言单继承结构的实现,  实现非常的简单, 但是体现了Java 的OO思想.

  

 1 ////Object.h
 2 #ifndef _Object_
 3 #define _Object_
 4 /*******************
 5 cls:
 6     类似于Java的接口, 子类想对某个函数进行重载 , 
 7     则只要在具体同名函数的位置替换掉原先的指针 .
 8     而子类想访问被覆盖掉的父类同名函数, 则直接访问
 9     父类的函数指针.
10     而私有函数, 则都在.c 文件中
11 pb:
12     公共数据结构, 数据结构在.h中
13     通过指针来访问自己的和父对象的公用数据
14     ((struct Pb*)pb[0])->size ; 访问了跟对象的public block的size
15 sb: 
16     私有的数据成员, 数据结构在.c中, 非本对象不可操作
17     ((struct Sb*)sb[0])->size
18 FLOOR:
19     该对象处于继承链的第几个位置, Root 为 0
20 注: pb 和 sb的 数据槽 都由new Object的对象来申请空间
21   初始化的方向为先初始化父类
22   析构方向为先析构子类
23 ********************/
24 struct Object;
25 //接口操作
26 typedef void (*PrintFn)(struct Object* self);
27 #define OBJECT_FLOOR 0
28 struct Class{
29     PrintFn p;
30 };
31 //公布的操作
32 struct Pb{
33     int size;
34 };
35 struct Object{
36     struct Class* cls;
37     void** pb;
38     void** sb;
39 };
40 void ObjectPrint(struct Object* self);
41 //申请基本的空间
42 //构建一个基本的空间, floor为子类所在的层, 根为第0层
43 struct Object* AllocObject(int floor);
44 //初始化对象
45 //如果o == NULL, 则Alloc一个空间
46 struct Object* CreateObject(struct Object* o);
47 #endif

  通过Cls公布类似java接口操作,  而pb 和 sb 分别为公布数据结构和私有数据结构, 并且私有函数都写在 .c 文件中.

  

 1 //Object.c
 2 #include<stdlib.h>
 3 #include<stdio.h>
 4 #include"Object.h"
 5 
 6 struct Sb{
 7     int num;
 8 };
 9 void ObjectPrint(struct Object* self){
10     struct Pb* p;
11     struct Sb* s;
12     p = (struct Pb*)self->pb[OBJECT_FLOOR];
13     s = (struct Sb*)self->sb[OBJECT_FLOOR];
14     printf("root Object Pb: %d\n root Object Sb: %d\n", p->size,s->num);
15 }
16 //申请基本的空间
17 //构建一个基本的空间, floor为子类所在的层, 根为第0层
18 struct Object* AllocObject(int floor){
19     if(floor <= 0){
20         //error
21     }
22     floor ++;
23     struct Object* o;
24     o = (struct Object*)malloc(sizeof(struct Object));
25     o->cls = (struct Class* )malloc(sizeof(struct Class));
26     //数据槽
27     o->pb = (void**) malloc(sizeof(void*) * floor );
28     o->sb = (void**) malloc(sizeof(void*) * floor );
29 }
30 
31 //初始化对象
32 //如果o == NULL, 则Alloc一个空间
33 struct Object* CreateObject(struct Object* o){
34     if(o == NULL)
35         o = AllocObject(OBJECT_FLOOR);
36     //初始化pb数据块
37     o->pb[OBJECT_FLOOR] = (struct Pb*)malloc(sizeof(struct Pb));
38     //初始化sb数据块
39     o->sb[OBJECT_FLOOR] = (struct Sb*)malloc(sizeof(struct Sb));
40     o->cls->p = &ObjectPrint;
41     ((struct Pb*)o->pb[OBJECT_FLOOR])->size = 1;
42     ((struct Sb*)o->sb[OBJECT_FLOOR])->num = 2;
43     return o;
44 }

     私有数据结构实现在.c 中,  私有函数也实现在.c 中

     而下面就是一个简单的Object2.h 对象

 

 1 ///Object2.h
 2 #ifndef _Object2_
 3 #define _Object2_
 4 #define OBJECT2_FLOOR 1
 5 #include"Object.h"
 6 //新子类的共享数据
 7 struct Pb2{
 8     int size;
 9 };
10 void ObjectPrint2(struct Object* self);
11 struct Object* CreateObject2(struct Object* o);
12 #endif

   Object2.h  实现了自己的数据结构 和公布了一个多态函数

 

 1 ///Object2.c
 2 #include"Object.h"
 3 #include"Object2.h"
 4 #include<stdio.h>
 5 #include<stdlib.h>
 6 void ObjectPrint2(struct Object* self){
 7     struct Pb2* p = (struct Pb2*)self->pb[1];
 8     printf("Object2 : %d \n",p->size);
 9     ObjectPrint(self);
10 }
11 struct Object* CreateObject2(struct Object* o){
12     if(o == NULL)
13         //处于继承链第一个位置
14         o = AllocObject(OBJECT2_FLOOR);
15     //初始化父对象
16     CreateObject(o);
17     //初始化pb数据块
18     o->pb[OBJECT2_FLOOR] = malloc(sizeof(struct Pb2));
19     //初始化sb数据块
20     o->sb[OBJECT2_FLOOR] = NULL;
21     //重载
22     o->cls->p = &ObjectPrint2;
23     ((struct Pb2*)o->pb[OBJECT2_FLOOR])->size =3;
24     return o;
25 }

         在第9行 , 调用了父类的该同名函数.

     以下是一个基本的测试:

    

////main.c
#include"Object2.h"
#include<stdlib.h>
int main(){
    struct Object* o = CreateObject2(NULL);
    o->cls->p(o);
}

编译命令:

gcc -c Object.c

gcc -c Object2.c

gcc -c main.c Obejct.o Object2.o

./a.out

测试成功! 

  通过pb 的连续内存块在继承结构中对象只能看到它自己和父对象的内存结构而不能发现该对象的子对象内存结构而父对象则照常使用属于他自己的内存空间从而实现了信息隐藏

并且每个对象的访问数据和操作都是统一的(主要是父对象):

1. 子对象指针和父对象指针都可以通过pb数据块进行操作自己的数据(从共享内存中找到自己的内存地址)

2. 子对象和父对象指针访问API都指向正确的实现(可以访问重载函数)

3. 私有数据都是从sb数据块获取

  C语言的继承和多态主要的核心是内存结构和CPU访问数据和函数的方式(参考C++对象继承内存模型)或者采用动态语言的机制进行查询访问.

源代码:

  https://files.cnblogs.com/tickobject/src.zip

项目代码地址:

    github.com/darkgem/js-engine

posted @ 2014-03-17 16:38  tickObject  阅读(420)  评论(5编辑  收藏  举报