zoukankan      html  css  js  c++  java
  • c struct pointer cast and object oriented

    https://stackoverflow.com/questions/3766229/casting-one-struct-pointer-to-another-c

    Please consider the following code.

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

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

    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?

    Any thoughts!

    up vote 31 down vote accepted

    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.

    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;

    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.

  • 相关阅读:
    day15—jQuery UI之widgets插件
    day14—jQuery UI 之dialog部件
    day13—CSS之导航栏
    day12—jQuery ui引入及初体验
    day11—前端学习之我不想看书
    struts2的action方法匹配以及通配符的使用
    Java中的static
    ActiveMQ的简单使用
    MS DOS 常用命令整理
    IntelliJ IDEA 中 Ctrl+Alt+Left/Right 失效
  • 原文地址:https://www.cnblogs.com/CreatorKou/p/9840642.html
Copyright © 2011-2022 走看看