gpt4 book ai didi

c - C 中 "emulate"多态性时使用结构成员和转换结构指针之间的区别

转载 作者:行者123 更新时间:2023-12-02 21:33:28 25 4
gpt4 key购买 nike

我不确定我的措辞在技术上是否正确,因此请纠正我的问题标题和正文。

所以基本上我的问题是关于在 C 中模拟多态性。例如,假设我有一棵树,并且有一个 struct tree_node 类型。我有一些函数可以帮助我插入节点、删除节点等,例如:

void tree_insert(tree_node **root, tree_node *new_node);

然后我开始为我的应用程序构建其他东西,并且需要使用这棵树来维护,比如说,家庭成员。但是对于人类,我有另一个结构体,我们称之为“struct human_node”,其定义如下,例如:

typedef struct human_node_ {
tree_node t_node;
char *name;
} human_node;

现在显然我想使用我为通用树构建的那些树实用函数。但它们采用 tree_node 指针。现在进行多态性模拟。所以这里有两个选择,一种是强制转换我的 human_node,一种是使用 human_node 中的 t_node 成员:

human_node *myfamily_tree_root, *new_family_guy;
//some initialization code and other code later...
tree_insert((tree_node **)&myfamily_tree_root, &(new_family_guy->t_node));

为了简洁起见,我将这两种方法都放在上面的一个函数调用中。

这正是我困惑的地方。那么我应该使用哪一个,更重要的是,为什么?

最佳答案

两者都是标准的,但一般来说,如果您可以避免类型转换,那么您应该选择避免类型转换的解决方案。

这种内联数据结构实现的一个常见问题是甚至不要求树节点(或等效元素)是结构中的第一个元素,因为您可能希望将节点输入到多个树中。那么你肯定想使用第二种方法。要在 tree_node 元素和包含的结构之间进行转换,您必须有一些黑魔法宏,但这是值得的。例如,在 avl 树的实现中,我有这些宏:

#ifndef offsetof
#define offsetof(s, e) ((size_t)&((s *)0)->e)
#endif

/* the bit at the end is to prevent mistakes where n is not an avl_node */
#define avl_data(n, type, field) ((type *)(void*)((char *)n - offsetof(type, field) - (n - (struct avl_node *)n)))

所以我可以有这样的东西:

struct foo {
int data;
struct avl_node tree_node_1;
struct avl_node tree_node_2;
};

int
tree_node_1_to_data(struct avl_node *x)
{
return avl_data(x, struct foo, tree_node_1)->data;
}

如果您选择使代码变得通用,您肯定希望引用对 tree_node 成员的引用,而不是将指针强制转换为结构体。

关于c - C 中 "emulate"多态性时使用结构成员和转换结构指针之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21874744/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com