我想创建一个通用堆栈。我想用一个链表来实现它。
我创建了这个结构stack_l:
typedef struct stack
{
void * data;
void (*copy)(void *o);
struct stack *next;
} stack_l;
我有一些问题:
- 结构的第二个字段是指向函数的指针,用于复制新数据(通过函数Push中的参数传递)。Push函数的原型是:
stack_l*Push(stack_l*head,void*d);
- 我将指针传递给函数副本的方式正确吗
- 我必须在Push??函数中实现它
- 是否有必要创建一个函数NewStack(例如)来初始化结构的字段,或者如果堆栈为空,最好只有一个Push函数来创建第一个元素,如果至少有一个元素,则在顶部添加新元素
- void*是否需要分配malloc
首先,stack
和stack_l
不需要不同的标识符。现在,回答您的问题:
您的Push
函数与stack_l
中copy
字段的类型不兼容。如果您想在struct
中包含一个指向(member-)函数的指针,使其看起来像C++,那么您仍然必须将对象传递给这些函数。
是的,您必须在某个地方实现您的功能,而这不能在struct stack
的定义范围内。这意味着您确实需要某种构造函数(如果您愿意,可以将其称为newStack
)。构造函数至少必须初始化函数指针(如果你想保留它们的话)。如果你选择不保留这些函数指针,你可以把初始化代码放在你的push
例程中,就像你建议的那样:
stack_l* stackPush(stack_l* head, void* content) {
// head might be NULL, meaning the stack is "empty" or it might be an actual pointer
// we don't care
stack_l* const front = malloc(sizeof(stack_l));
*front = (stack_l){.data = content, .next = head};
return front;
}
请注意,您必须明确说明空堆栈是什么。因此,为了清楚起见,您可能需要实现一个构造函数:
stack_l* stackCreateEmpty() {
retun NULL;
}
甚至可能是一个析构函数:
void stackDestroyEmpty(stack_l* s) {
assert(s == NULL && "Tried to destroy non-empty stack.");
}
对于您的最后一个问题:如上所述,您必须使用malloc
来获得空间来容纳stack_l
对象,除此之外,您不需要为void*
成员分配额外的空间,因为它是stack_l
的一部分。