<分区>
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,
visit the help center .
关闭 10 年前 。
我在读一本关于在 C 中实现 OOP 的书,发现了这段代码:
void delete (void * self)
{
const struct Class ** cp = self;
if (self && * cp && (* cp) -> dtor)
self = (* cp) -> dtor(self);
free(self);
}
我想知道为什么作者创建了双指针而不是单指针
像这样
void delete (void * self)
{
const struct Class * cp = self;
if (self && cp && cp -> dtor)
self = cp -> dtor(self);
free(self);
}
有什么区别吗?
在作者的对象系统中,每个对象结构都包含一个指向其类的指针作为其第一个元素:
typedef struct Object1 {
Class *myclass;
int data;
} Object1;
typedef struct Object2 {
Class *myclass;
double data;
} Object2;
这意味着通过将指向任何对象的 void *
指针视为 Class **
指针,可以在不知道对象的实际类型的情况下跟踪类指针.这是标准允许的,因为:
c11
6.7.2.1 Structure and union specifiers
15 [...] A pointer to a
structure object, suitably converted, points to its initial member (or if that member is a
bit-field, then to the unit in which it resides), and vice versa. [...]
因此任何指针 Object1 *
或 Object2 *
等都可以转换为指向其第一个元素的指针,即 Class **
(因为两者的第一个元素是 Class *
类型,指向第一个元素的指针是 Class **
类型)。参见 In C, does a pointer to a structure always point to its first member? 获取更多信息。
这是一种合法的方法,但有点难以遵循。等价于写
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);
}