// RT-Thread对象模型采用结构封装中使用指针的形式达到面向对象中多态的效果,例如: // 抽象父类 #include <stdio.h> #include <assert.h> struct parent { int a; //反映不同类别属性的方法 void (*vfunc)(int a); }; // 继承自parent的子类 struct child { struct parent p; int b; }; // 父类的方法调用 void parent_vfunc(struct parent *self, int a) { assert(self != NULL); assert(self->vfunc != NULL); // 调用对象本身的虚拟函数 self->vfunc(a); } // 父类的虚函数实现 static void Parent_FuncAction(int a) { printf(" Father 父对象动作 传入的参数 = %d ", a); } // 父类的构造函数 void parent_init(struct parent* self) { self->vfunc = Parent_FuncAction; } // 子类的方法调用 void child_vfunc(struct child *self, int a) { struct parent* parent; // 强制类型转换获得父类指针 parent = (struct parent*) self; assert(parent != NULL); parent->vfunc(a); } // 子类的虚函数实现 static void Child_FuncAction(int a) { printf(" Son 子对象动作 传入的参数 = %d ", a); } // 子类的构造函数 void child_init(struct child* self) { struct parent* parent; // 强制类型转换获得父类指针 parent = (struct parent*) self; assert(parent != NULL); // 设置子类的虚拟函数 parent->vfunc = Child_FuncAction; // 多态要求父类和子类的具有多态关系的函数之间的函数名和签名保持一致。 // 从这里的写法,也可以看出来。 } int main() { // 这里可以结合RT Thread 的PIN 设备驱动, // 掌握其是如何使用这些概念的,以便:1提高C语言的运用能力 、2有利于深入理解RT Thread等面向对象思想。 //一: struct parent Parent; struct child Child; parent_init(&Parent); parent_vfunc(&Parent, 88); // 看第一个形参,是struct parent*。传入的对象是Parent。 // 有点父类指针指向父类对象的意思。 child_init(&Child); // 子类先初始化 parent_vfunc( (struct parent*)(&Child), 88); // 看第一个形参,这里有点父类指针指向子类对象的意思。 // 上面两段代码的效果:同一个函数被调用,传入不同的形参,达到不同的效果。这就达到了C语言实现多态的目的。 //二: child_vfunc(&Child, 66); child_vfunc((struct child*)&Parent, 66); printf(" hello "); } // 缺点:上述代码,子类对象无法调用父类的方法。 // 因为子类对象在构造的时候,子类的方法是覆盖式重写父类的方法的。所以也就不存在父类的方法一说了。 // 如果子类声明如下,那么子类对象就能同时保持父类和子类的方法。 //struct child //{ //struct parent p; 父类本身有自己的方法。 //void (*vfunc)(int a); 这是专属于子类的方法。 <== 同时保持父类和子类的方法。 //int b; //}; /* // C 多态 一角,展示的一个 小例子 typedef struct ClassCoreObj{ int a; }ClassCoreObj; typedef struct ClassSon_{ ClassCoreObj Obj; int a; }ClassSon; int main(void) { int testValue; ClassCoreObj CoreObj = {88}; // ClassSon Son = {CoreObj, 99}; Error 编译报错 // 应该是son.obj.a=coreobj的时候出的错,编译器不知道要类型转换. ClassSon Son; Son.Obj = CoreObj; Son.a = 99; testValue = ((ClassCoreObj*)&Son)->a; // 访问父类的成员a printf("testValue = %d ", testValue); testValue = Son.a; // 访问子类的成员a printf("testValue = %d ", testValue); } */
.