来自void *的双指针和单指针?

时间:2012-08-20 10:14:09

标签: c pointers

我正在读一本关于在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);
}

有什么不同吗?

3 个答案:

答案 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;
}