Прежде всего, вам не нужны разные идентификаторы для stack
и stack_l
. Теперь на ваши вопросы:
Ваша функция Push
несовместима с типом поля copy
в stack_l
. Если вы хотите включить указатель на (member-) функции в вашем struct
, чтобы он выглядел как 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
.