0. 概述
- 通过struct 实现封装
- 通过函数指针实现虚表
- 成员包括:属性 和 方法
- 属性使用普通的数据类型,方法使用函数指针类型
- 通过函数指针成员 提供 对象./-> 成员的访问形式
- 通过包含父类的实例对象super 实现继承关系
- 通过在子类中实现虚表中的方法,修改父类中的虚表指针指向子类实现的虚表实例来实现多态
- 每一个方法都带有显式的pthis指针 表征操作该方法的当前对象
1. 虚表的本质
将父类的方法的实现推迟到子类中去,即后绑定绑定就是,父类的虚表中的函数指针指向子类的实现函数
2. 虚表的实现
采用函数指针,并定义虚表结构体
eg.
#define sensor_methods \
int (*get_id)(void* pthis); \
struct struct sensor_vmt {
int (*get_id)(void* pthis);
};
#define sensor_data \
int id;
定义基类:
struct sensor {
struct sensor_vmt* vptr; ///< 指向虚表的函数指针
sensor_methods ///< 提供 对象./->成员函数的访问形式
sensor_data
};
///< pthis: sensor 对象, vmt: 虚表指针
void sensor_init(void* pthis, void* vmt)
{
struct sensor* _pthis = (struct sensor*)pthis;
pthis->vptr = (struct sensor_vmt*)vmt;
pthis->get_id = pthis->vptr->get_id;
}
定义子类:
#define compass_methods_alone \
void (*read_raw)(void* pthis, float data[3]);
#define compass_methods \
sensor_methods \ ///< compass 也是sensor 所以包含sensor的方法, 继承了多少层就要包含所有父类的方法
compass_methods_alone
#define compass_data \
///< int id;
struct compass_vmt {
compass_methods ///< 子类的虚表定义
};
struct compass_sensor {
struct sensor super; ///< 继承自sensor
struct compass_vmt* vptr; ///< 指向虚表的函数指针,如是则该类可被继续继承
compass_methods ///< 方法,提供对象./-> 函数的访问形式
compass_data ///< 数据
};
///< 实现
static int comp_get_id(void* pthis)
{
//......
}
///< 实现
static void comp_read_raw(void* pthis, float data[3])
{
//......
}
///< 虚表
static compass_vmt vmt = {
.get_id = comp_get_id,
.read_raw = comp_read_raw,
};
void compass_sensor_init(void* pthis, void* vmt)
{
pthis->vmt = (struct compass_vmt*)vmt;
sensor_init(&pthis->super, vmt); ///< 基类的初始化方法
pthis->get_id = pthis->vmt->get_id;
pthis->read_raw = pthis->vmt->read_raw;
}
///< 示例
struct compass_sensor xxx;
compass_sensor_init(&xxx, &vmt)
xxx.get_id(&xxx);
struct sensor* ps = (struct sensor)&xxx;
ps->get_id(ps);