|
RT_Thread是类Unix风格的代码风格,里面大量应用了C语言的对象化模型技术,我的基础目的是学习这个操作系统的,后面被它的面向对象编程的思想
所吸引住,与其说是在研究操作系统不如说是在感受前辈门的抽象编程的思想。今天和大家分享RT_Thread的对象化模型技术的基本原理。它实质是运用了c语
言的面向对象的特征思想。
C语言面向对象的三大特征:
1、封装,隐藏内部实现
2、继承,复用现有代码
3、多态,改写对象行为
RT_Thread里面林林总总的封装思想,详细的拆分都可以寻觅到这三个影子。
下面普及基础知识
封装是一种信息隐蔽技术,它体现于类的说明,是对象的重要特性。封装使数据和加工该数据的方法(函数)封装为一个整体,以实现独立性很强的模块,使得用户只能见到对象的外特性(对象能接受哪些消息,具有那些处理能力),而对象的内特性(保存内部状态的私有数据和实现加工能力的算法)对用户是隐蔽的。封装的目的在于把对象的设计者和对象者的使用分开,使用者不必知晓行为实现的细节,只须用设计者提供的消息来访问该对象。
继承性是子类自动共享父类之间数据和方法的机制。它由类的派生功能体现。一个类直接继承其它类的全部描述,同时可修改和扩充。继承具有传递性。继承分为单继承(一个子类只有一父类)和多重继承(一个类有多个父类,当前RT-Thread的对象系统不能支持)。类的对象是各自封闭的,如果没继承性机制,则类对象中数据、方法就会出现大量重复。继承不仅支持系统的可重用性,而且还促进系统的可扩充性。具体代码片段如下:
#include <stdio.h>
#include <stdlib.h>
//父类
struct parent_class
{
int a,b;
char *c;
};
//子类
struct child_class
{
struct parent_class p;
int a,b;
};
//demo test
void test_demo(void)
{
struct child_class child,*child_ptr;
struct parent_class *parent_ptr;
child_ptr = &child;
parent_ptr = (struct parent_class *)&child;
parent_ptr->a = 1;
parent_ptr->b = 2;
parent_ptr->c = "lable";
child_ptr->a = 100;
child_ptr->b = 200;
printf("parent_ptr->a = %d\r\nparent_ptr->b = %d\r\nparent_ptr->c = %s\r\n\r\n",parent_ptr->a,parent_ptr->b,parent_ptr->c);
printf("child_ptr->a = %d\r\nchild_ptr->b = %d\r\n",child_ptr->a,child_ptr->b);
}
int main()
{
printf("Inherit test\n");
test_demo();
return 0;
}
执行结果:
Inherit test
parent_ptr->a = 1
parent_ptr->b = 2
parent_ptr->c = lable
child_ptr->a = 100
child_ptr->b = 200
多态,对象根据所接收的消息而做出动作。同一消息为不同的对象接受时可产生完全不同的行动,这种现象称为多态性。利用多态性用户可发送一个通用的信息,而将所有的实现细节都留给接受消息的对象自行决定,如是,同一消息即可调用不同的方法。例如:RT-Thread系统中的设备:抽象设备具备接口统一的读写接口。串口是设备的一种,也应支持设备的读写。但串口的读写操作是串口所特有的,不应和其他设备操作完全相同,例如操作串口的操作不应应用于SD卡设备中。多态性的实现受到继承性的支持,利用类继承的层次关系,把具有通用功能的协议存放在类层次中尽可能高的地方,而将实现这一功能的不同方法置于较低层次,这样,在这些低层次上生成的对象就能给通用消息以不同的响应。RT-Thread对象模型采用结构封装中使用函数指针的形式达到面向对象中多态的效果。具体代码片段如下:
#include <stdio.h>
#include <stdlib.h>
//抽象父类
struct parent_class
{
int a;
void (*vfunc)(struct parent_class *,int a);
};
//抽象父类的方法
void parent_class_vfunc(struct parent_class *parent_self_ptr,int a)
{
//调用对象自己本身的虚拟函数
printf("parent_class_vfunc\n");
parent_self_ptr->vfunc(parent_self_ptr,a);
}
//子类继承parent_class
struct child_class1
{
struct parent_class parent;
int b;
};
//子类虚拟函数实现
void child1_class_vfunc(struct child_class1 *child1_self_ptr,int a)
{
printf("child1_class_vfunc\n");
child1_self_ptr->b = a + 10;
}
//子类构造函数
void child1_class_init(struct child_class1 *child1_self_ptr)
{
struct parent_class *parent;
//获取子类的父类指针
parent = (struct parent_class *)child1_self_ptr;
//设置子类的虚函数
parent->vfunc = child1_class_vfunc;
}
//子类继承parent_class
struct child_class2
{
struct parent_class parent;
int b;
};
//子类虚拟函数实现
void child2_class_vfunc(struct child_class2 *child2_self_ptr,int a)
{
printf("child2_class_vfunc\n");
child2_self_ptr->b = a + 10;
}
//子类构造函数
void child2_class_init(struct child_class2 *child2_self_ptr)
{
struct parent_class *parent;
//获取子类的父类指针
parent = (struct parent_class *)child2_self_ptr;
//设置子类的虚函数
parent->vfunc = child2_class_vfunc;
}
int main()
{
struct child_class1 child1,*child1_ptr;
struct child_class2 child2,*child2_ptr;
struct parent_class *parent_ptr;
//child1初始化
child1_ptr = &child1;
parent_ptr = (struct parent_class *)child1_ptr;
child1_ptr->b = 10;
child1_class_init(child1_ptr);
parent_ptr->vfunc((struct parent_class *)child1_ptr,20);
//child2初始化
child2_ptr = &child2;
parent_ptr = (struct parent_class *)child2_ptr;
child2_ptr->b = 20;
child2_class_init(child2_ptr);
parent_ptr->vfunc((struct parent_class *)child2_ptr, 20);
return 0;
}
执行结果:
child1_class_vfunc
child2_class_vfunc
|
阿莫论坛20周年了!感谢大家的支持与爱护!!
你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。
|