我有两个函数完全相同,但是在两个不同类型的struct中,这两种类型的struct非常相似。
想象一下,我有这两个结构。
typedef struct nodeOne{
Date *date;
struct nodeOne *next;
struct nodeOne *prev;
}NodeOne;
typedef struct nodeTwo{
Date *date;
struct nodeTwo *next;
struct nodeTwo *prev;
}NodeTwo;
由于我破坏每个列表的函数几乎是相同的(只是参数的类型不同)我想只做一个函数来制作两个变量。
我有这两个功能
void destroyListOne(NodeOne **head, NodeOne **tail){
NodeOne *aux;
while (*head != NULL){
aux = *head;
*head = (*head)->next;
free(aux);
}
*tail = NULL;
}
和这一个:
void destroyListTwo(NodeTwo **head, NodeTwo **tail){
NodeTwo *aux;
while (*head != NULL){
aux = *head;
*head = (*head)->next;
free(aux);
}
*tail = NULL;
}
由于它们非常相似,我想这样做:
void destroyList(void **ini, void **end, int listType){
if (listType == 0) {
NodeOne *aux;
NodeOne head = (NodeOne) ini;
NodeOne tail = (NodeOne) ed;
}
else {
NodeTwo *aux;
NodeTwo head = (NodeTwo) ini;
NodeTwo tail = (NodeTwo) ed;
}
while (*head != NULL){
aux = *head;
*head = (*head)->next;
free(aux);
}
*tail = NULL;
}
正如您现在可能无法正常工作,但我想知道是否可以实现这一目标。
我必须保持两种结构。
答案 0 :(得分:2)
正如@Dancrumb所说,这里有一些设计问题,我不建议你做你想做的事。
也就是说,如果nodeOne
和nodeTwo
总是相同(我会< strong>从不依赖于生产代码。)
您可以选择一个,并始终投射到它(颤抖)。因为它们是具有不同名称的相同结构,所以演员工作:
void destroyList(void *ini, void *end, int listType){
NodeOne *aux = NULL;
NodeOne **head = ini;
NodeOne **tail = end;
while (*head != NULL){
aux = *head;
*head = (*head)->next;
free(aux);
}
*tail = NULL;
}
另请注意,在C中,您不需要显式强制转换,因为void *可以在没有强制转换的情况下隐式转换为任何其他指针类型。
但严重的是,请不要这样做。它脆弱,不可维护,容易出错。
<小时/> 看了@Torp的回答后,我想详细说明问题的精神和答案。有了@Torp代码的错误修复(它没有编译,并且有几个指针问题),它可以使其工作。也就是说,我仍然认为你不应该让它发挥作用。
特别是当我们谈论C(而不是C ++)时,我肯定会将destroy函数分开用于单独的列表类型。尽可能避免使用剪切和粘贴代码,但在这种情况下,我认为安全性,清晰度和可维护性都是赢家。我的意见当然。您的里程可能会有所不同:)
答案 1 :(得分:2)
尽管我不愿意这样说,但这就是为什么模板是用C ++发明的。你确定你不能使用它吗?
这样的事情应该有效:
void destroyList(void **ini, void **end, int listType)
{
void *aux;
void *head = ini;
void *tail = end;
while (*head != NULL){
if (listType == 0) {
aux = (NodeOne *)*head;
*head = ((NodeOne*)*head)->next;
free((NodeOne*)aux;
} else {
... same thing with casts to NodeTwo* ...
}
}
*tail = NULL;
}
我不确定我是否将所有类型的演员阵容放在任何地方,但你明白了。
答案 2 :(得分:0)
如果我正在设计这个,我已经完成了:
typedef struct node{
Date *date;
struct node *next;
struct node *prev;
} Node;
由于NodeOne
和NodeTwo
相同,为什么有两种不同的类型?
如果有某些原因导致我失踪,那么我会延伸:
typedef struct nodeOne {
Node nodeInfo;
/* additional */
} NodeOne
typedef struct nodeTwo {
Node nodeInfo;
/* additional */
} NodeTwo
然后,只需将nodeInfo
字段传递给Node操作函数。
答案 3 :(得分:0)
编写一个包含所有函数的#define,只需将函数名和结构类型作为参数。
#define DECLARE_DESTRUCTION_FUNCT(_name_, _type_) void _name_(_type_ **head, _type_ **tail){\
_type_ *aux;\
\
while (*head != NULL){\
aux = *head;\
*head = (*head)->next;\
free(aux);\
}\
*tail = NULL;\
}
DECLARE_DESTRUCTION_FUNCT(destroyListOne, NodeOne)
DECLARE_DESTRUCTION_FUNCT(destroyListTwo, NodeTwo)
这种类型从C ++复制模板。 带来了编译时类型检查的好处。