在作者的对象系统中,每个对象结构都包含一个指向其类的指针作为其第一个元素:
typedef struct Object1 {
Class *myclass;
int data;
} Object1;
typedef struct Object2 {
Class *myclass;
double data;
} Object2;
这意味着通过将void *
指向任何对象的指针视为Class **
指针,可以在不知道对象的实际类型的情况下跟踪类指针。这是标准允许的,因为:
c11
6.7.2.1 结构和联合说明符
15 [...] 指向结构对象的指针,经过适当转换,指向其初始成员(或者如果该成员是位域,则指向它所在的单元),反之亦然。[...]
因此,任何指针等都Object1 *
可以Object2 *
转换为指向其第一个元素的指针,即Class **
(因为任何一个的第一个元素是 type Class *
,指向第一个元素的指针是 type Class **
)。请参阅在 C 中,指向结构的指针是否总是指向其第一个成员?了解更多信息。
这是一种合法的方法,但有点难以遵循。一个等价物是写
typedef struct BaseObject {
Class *myclass;
} BaseObject;
并要求每个对象结构都包含一个BaseObject
实例作为其第一个成员;然后该delete
函数将self
转换为BaseObject *
并写入((BaseObject *) self)->myclass->dtor
:
void delete (void * self)
{
BaseObject *base = self;
if (self && base->myclass && base->myclass—>dtor)
self = base->myclass->dtor(self);
free(self);
}