使用相同格式将void强制转换为struct

使用相同格式将void强制转换为struct,c,C,我有三个几乎完全相同格式的结构 struct name_basics { char *nconst; char *primaryName; }; struct title_basics { char *tconst; char *primaryTitle; }; 还有一个,但你明白了。 基本上,我需要每个结构都有一个函数,而我想把它缩短为一个 struct nameNode *newNameNode(struct name_basics data) {

我有三个几乎完全相同格式的结构

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

struct title_basics {
    char *tconst;
    char *primaryTitle;
};
还有一个,但你明白了。 基本上,我需要每个结构都有一个函数,而我想把它缩短为一个

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

是否有任何方法可以将它们作为void传递,将它们转换为某种抽象结构,并使用它们的数据?

不幸的是,在C中没有很好的多态性处理方法。无论您选择什么方法,它最多都是可以接受的。在您的情况下,由于结构看起来完全相同,所以我会考虑将结构的数量减少到一个,并将其重命名为通用的。 但如果您不想这样做,那么执行多态性的一种非常通用的方法是在结构中使用联合。是好是坏取决于你。我不会用它

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

在您的例子中,其中一些可以简化,因为结构非常相似,但这是一种通用方法。

不幸的是,在C中没有很好的多态性处理方法。无论您选择什么方法,它最多都是可以接受的。在您的情况下,由于结构看起来完全相同,所以我会考虑将结构的数量减少到一个,并将其重命名为通用的。 但如果您不想这样做,那么执行多态性的一种非常通用的方法是在结构中使用联合。是好是坏取决于你。我不会用它

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


在您的例子中,其中一些可以简化,因为结构非常相似,但这是一种通用的方式。

结构具有完全相同的格式。您不能只使用一个并将其重命名为泛型吗?将它们作为指针传递,然后让子对象接受一个
void*
。或者,您可以使用三个结构的并集。我知道这不是问题的重点,但是在使用malloc时,应该在使用它之前检查返回值除此之外,没有“干净”的方法来模拟C中的覆盖,但有些人使用宏、联合(技术上未定义)、void*cast(在某些用法中也未定义)。。。我个人从未见过工会做事的方式出了问题,而且通常认为这是可行的。你也可以像@klutt建议的那样,拥有一个包含所有通用字段的子结构。如果我所经过的只是一片空白,那就没有办法知道该投什么了to@DavidC.Rankin类型不兼容,因为名称不匹配。结构具有完全相同的格式。您不能只使用一个并将其重命名为泛型吗?将它们作为指针传递,然后让子对象接受一个
void*
。或者,您可以使用三个结构的并集。我知道这不是问题的重点,但是在使用malloc时,应该在使用它之前检查返回值除此之外,没有“干净”的方法来模拟C中的覆盖,但有些人使用宏、联合(技术上未定义)、void*cast(在某些用法中也未定义)。。。我个人从未见过工会做事的方式出了问题,而且通常认为这是可行的。你也可以像@klutt建议的那样,拥有一个包含所有通用字段的子结构。如果我所经过的只是一片空白,那就没有办法知道该投什么了to@DavidC.Rankin类型不兼容,因为名称不匹配。在什么方面比单独使用独立函数更好?@n.m.我没有说这更好,但这是OP要求的。OP已经有了一些东西,他们希望改进。如果你的建议不是改进,为什么要改进?@n.m.是否改进是主观的,为了对此事有实际的意见,我需要看更多的代码。但OP说“基本上我需要每个结构都有一个函数,而我想把它缩短为一个。”OP要求改进。如果你认为这不是一个进步,不要建议它。你认为这是一种进步吗?也就是说,您真的会在代码中使用它吗?这没有什么主观的。在什么方面它比单独的独立功能更好?@n.m.我没有说它更好,但这是OP要求的。OP已经有了一些东西,他们希望改进。如果你的建议不是改进,为什么要改进?@n.m.是否改进是主观的,为了对此事有实际的意见,我需要看更多的代码。但OP说“基本上我需要每个结构都有一个函数,而我想把它缩短为一个。”OP要求改进。如果你认为这不是一个进步,不要建议它。你认为这是一种进步吗?也就是说,您真的会在代码中使用它吗?这一点也不主观。