我正在读一本关于在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);
}
有什么不同吗?
答案 0 :(得分:5)
在作者的对象系统中,每个对象struct都包含一个指向其类的指针的第一个元素:
typedef struct Object1 {
Class *myclass;
int data;
} Object1;
typedef struct Object2 {
Class *myclass;
double data;
} Object2;
这意味着通过将void *
指向任何对象的指针视为Class **
指针,可以在不知道对象的实际类型的情况下遵循类指针。这是标准允许的,因为:
6.7.2.1结构和联合规范
15 [...]指向a的指针 结构对象,适当转换,指向其初始成员(或者如果该成员是a bit-fi eld,然后到它所在的单位),反之亦然。 [...]
因此任何指针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;
并要求每个对象struct包含一个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);
}
答案 1 :(得分:1)
在此系统中,每个对象在第一个字段中包含指向其类的指针。实际上,Class **c = self
从对象实例中获取类结构。
答案 2 :(得分:0)
由于结构设计:
*(const struct Class **)p=class;
在那里: http://humelab.googlecode.com/svn-history/r3/trunk/ooc/new.c
见
void * new(const void *_class,...)
{
const struct Class *class=_class;
void *p=calloc(1,class->size);
assert(p);
*(const struct Class **)p=class; //<------look here!
if(class->ctor)
{
va_list ap;
va_start(ap,_class);
p=class->ctor(p,&ap);
va_end(ap);
}
return p;
}