将一个结构指针转换为另一个 - C [英] Casting one struct pointer to another - C

查看:27
本文介绍了将一个结构指针转换为另一个 - 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*.但是在返回值中它被转换为object* 的类型.

In the cons function, variable ptr is of type cons_object*. But in the return value it is converted to type of object*.

  1. 我想知道这怎么可能,因为 cons_objectobject 是不同的结构.
  2. 做这样的事情有什么问题吗?
  1. I am wondering how this is possible because cons_object and object are different structs.
  2. Are there any issues in doing stuff like this?

任何想法!

推荐答案

这很好,是在 C 中实现面向对象"的一种相当常见的技术.因为 struct 的内存布局在 C 中定义明确,只要两个对象共享相同的布局,那么您就可以安全地在它们之间转换指针.也就是说,type 成员在 object 结构中的偏移量与 cons_object 结构中的相同.

This is fine and is a fairly common technique for implementing "object-orientation" in C. Because the memory layout of structs is well-defined in C, as long as the two object share the same layout then you can safely cast pointers between them. That is, the offset of the type member is the same in the object struct as it is in the cons_object struct.

在这种情况下,type 成员告诉 API objectcons_object 还是 foo_object 或某种其他类型的对象,因此您可能会看到类似这样的内容:

In this case, the type member tells the API whether the object is a cons_object or foo_object or some other kind of object, so you might be see something like this:

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
}

更常见的是,我似乎有将父"类定义为子"类的第一个成员的实现,如下所示:

More commonly, I've seem implementations where the "parent" class is defined as the first member of the "child" class, like so:

typedef struct {
    enum type type;
} object;

typedef struct {
    object parent;

    object *car;
    object *cdr;
} cons_object;

这在很大程度上以相同的方式工作,除了您有一个强有力的保证,即子类"的内存布局将与父母相同.也就是说,如果您向基础"object 添加一个成员,它会自动被子项选取,而您不必手动确保所有结构都同步.

This works in largely the same way, except you've got a strong gaurantee that the memory layout of the child "classes" will be the same as the parents. That is, if you add a member to the 'base' object, it'll automatically be picked up by the children and you won't have to manually make sure all of the structures are in sync.

这篇关于将一个结构指针转换为另一个 - C的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆