将一个结构体指针转换为其他C

请考虑以下代码。

enum type {CONS, ATOM, FUNC, LAMBDA};

typedef struct{
  enum type type;
} object;

typedef struct {
  enum type type;
  object *car;
  object *cdr;
} cons_object;

object *cons (object *first, object *second) {
  cons_object *ptr = (cons_object *) malloc (sizeof (cons_object));
  ptr->type = CONS;
  ptr->car = first;
  ptr->cdr = second;
  return (object *) ptr;
}

在cons函数中,变量ptr的类型为cons_object *。但是在返回值中,它被转换为对象*的类型。

>我想知道这是可能的,因为cons_object和object是不同的结构体。
>做这样的事情有什么问题吗?

有什么想法吗!

这是很好的,是在C中实现“面向对象”的相当常见的技术。因为结构体的内存布局在C中被很好地定义,只要两个对象共享相同的布局,那么你可以安全地在它们之间投掷指针。也就是说,类型成员的偏移量在对象结构中与在cons_object结构体中的偏移相同。

在这种情况下,类型成员告诉API对象是否为cons_object或foo_object或其他类型的对象,因此您可能会看到如下:

void traverse(object *obj)
{
    if (obj->type == CONS) {
        cons_object *cons = (cons_object *)obj;
        traverse(cons->car);
        traverse(cons->cdr);
    } else if (obj->type == FOO) {
        foo_object *foo = (foo_object *)obj;
        traverse_foo(foo);
    } else ... etc
}

更常见的是,我已经看到“父类”类被定义为“小孩”类的第一个成员的实现,像这样:

typedef struct {
    enum type type;
} object;

typedef struct {
    object parent;

    object *car;
    object *cdr;
} cons_object;

除了你有一个强大的gaurantee,孩子“班级”的记忆布局将与父母一样,这一点大致相同。也就是说,如果您将一个成员添加到“base”对象,它将自动由孩子们拾取,您不必手动确保所有结构都处于同步状态。

http://stackoverflow.com/questions/3766229/casting-one-struct-pointer-to-other-c

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:将一个结构体指针转换为其他C