简体   繁体   English

将 void 转换为具有相同格式的结构

[英]casting void to struct with same format

I have three structs with almost the same exact format.我有三个具有几乎相同格式的结构。

struct name_basics {
    char *nconst;
    char *primaryName;
};

struct title_basics {
    char *tconst;
    char *primaryTitle;
};

And one more, but you get the point.还有一个,但你明白了。 Basically I need a function for each struct, whereas I would like to shorten it down to one.基本上我需要一个 function 为每个结构,而我想把它缩短到一个。

struct nameNode *newNameNode(struct name_basics data) {
    struct nameNode *node = malloc(sizeof(struct nameNode));
    node->data = data;
    node->left = NULL;
    node->right = NULL;
    return node;
}

struct titleNode *newTitleNode(struct title_basics data) {
    struct titleNode *node = malloc(sizeof(struct titleNode));
    node->data = data;
    node->left = NULL;
    node->right = NULL;
    return node;
}

Is there any way to pass them as void, cast them to a sort of abstract struct, and use their data?有没有办法将它们作为 void 传递,将它们转换为一种抽象结构,并使用它们的数据?

Unfortunately, there is no nice way of doing polymorphism in C.不幸的是,在 C 中没有很好的多态性方法。 Whatever method you choose, it will at best be acceptable.无论您选择哪种方法,它充其量都是可以接受的。 In your case, since the structs looks exactly the same, I would consider reducing the number of structs to one and rename it to something generic.在您的情况下,由于结构看起来完全相同,我会考虑将结构的数量减少到一个并将其重命名为通用名称。

But if you don't want to do that, a pretty generic way to do polymorphism is to use a union inside a struct.但是,如果您不想这样做,一种非常通用的多态性方法是在结构中使用联合。 Whether it's good or bad is up to you.是好是坏,就看你自己了。 I would not use it.我不会使用它。

struct myStruct {
    enum {name, title} type;
    union {
        struct name_basics a;
        struct title_basics b;
    } data;
};

void *newNode(struct myStruct data) {
    struct nameNode *nn;
    struct titleNode *tn;
    void *ret;
    switch(data.type) {
    case name:
        nn = malloc(sizeof(struct name_basics));
        nn->data = data.data.a;
        nn->left = nn->right = NULL;
        ret = (void*)nn;
        break;
    case title:
        tn = malloc(sizeof(struct title_basics));
        tn->data = data.data.b;
        tn->left = tn->right = NULL;
        ret = (void*)tn;
        break;
    }
    return ret;
}

Some of this could be simplified in your case because the structs are so similar, but this is a generic way.在您的情况下,其中一些可以简化,因为结构非常相似,但这是一种通用方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM