M
MartinBroadhurst
Now that Jon is safely tucked up, I'd like to ask a C question.
Suppose I have a linked list package, and I want to make a stack out
of it.
I don't want to do this:
typedef linkedlist stack;
#define stack_create linkedlist_create
#define stack_delete linkedlist_delete
#define stack_push linkedlist_add_head
#define stack_pop linkedlist_remove_head
Because that doesn't prevent someone from doing this:
stack *s = stack_create();
/* Some time later */
linkedlist_add_tail(s, "FISH");
So I need to make stack a new type, but I still want to reuse the
linked list.
As far as I can see, there are two ways of doing this.
Firstly, I could declare a stack as an indentical structure to the
linked list...
typedef struct {
/* Exactly the same as linkedlist */
} stack;
....and then implement the functions by calling the corresponding
linkedlist ones with a cast:
stack *stack_create(void)
{
return (stack*)linkedlist_create();
}
void stack_delete(stack *s)
{
linkedlist_delete((linkedlist*)s);
}
void stack_push(stack *s, void *data)
{
linkedlist_add_head((linkedlist*)s, data);
}
void *stack_pop(stack *s)
{
return linkedlist_remove_head((linkedlist*)s);
}
Second, I could put a pointer to a linkedlist inside the stack...
typedef struct {
linkedlist *list;
} stack;
....and then implement the functions by forwarding to the contained
list:
stack *stack_create(void)
{
stack *s = malloc(sizeof(stack));
if (s) {
s->list = linkedlist_create();
}
return s;
}
void stack_delete(stack *s)
{
if (s) {
linkedlist_delete(s->list);
free(s);
}
}
void stack_push(stack *s, void *data)
{
linkedlist_add_head(s->list, data);
}
void *stack_pop(stack *s)
{
return linkedlist_remove_head(s->list);
}
Are both of these methods valid, and if so, is there a reason to
prefer one over the other?
Is there another way?
Martin
Suppose I have a linked list package, and I want to make a stack out
of it.
I don't want to do this:
typedef linkedlist stack;
#define stack_create linkedlist_create
#define stack_delete linkedlist_delete
#define stack_push linkedlist_add_head
#define stack_pop linkedlist_remove_head
Because that doesn't prevent someone from doing this:
stack *s = stack_create();
/* Some time later */
linkedlist_add_tail(s, "FISH");
So I need to make stack a new type, but I still want to reuse the
linked list.
As far as I can see, there are two ways of doing this.
Firstly, I could declare a stack as an indentical structure to the
linked list...
typedef struct {
/* Exactly the same as linkedlist */
} stack;
....and then implement the functions by calling the corresponding
linkedlist ones with a cast:
stack *stack_create(void)
{
return (stack*)linkedlist_create();
}
void stack_delete(stack *s)
{
linkedlist_delete((linkedlist*)s);
}
void stack_push(stack *s, void *data)
{
linkedlist_add_head((linkedlist*)s, data);
}
void *stack_pop(stack *s)
{
return linkedlist_remove_head((linkedlist*)s);
}
Second, I could put a pointer to a linkedlist inside the stack...
typedef struct {
linkedlist *list;
} stack;
....and then implement the functions by forwarding to the contained
list:
stack *stack_create(void)
{
stack *s = malloc(sizeof(stack));
if (s) {
s->list = linkedlist_create();
}
return s;
}
void stack_delete(stack *s)
{
if (s) {
linkedlist_delete(s->list);
free(s);
}
}
void stack_push(stack *s, void *data)
{
linkedlist_add_head(s->list, data);
}
void *stack_pop(stack *s)
{
return linkedlist_remove_head(s->list);
}
Are both of these methods valid, and if so, is there a reason to
prefer one over the other?
Is there another way?
Martin