【发布时间】:2021-10-22 10:28:36
【问题描述】:
假设有一个员工ADT,比如
//employee.h
typedef struct employee_t employee_t;
employee_t* employee_create(char* company, char* department, char* position);
void employee_free(employee_t* me);
,客户端代码是
#include "employee.h"
employee_t* Kevin = employee_create("Facebook", "Marketing", "Sales");
employee_t* John = employee_create("Microsoft", "R&D", "Engineer");
现在客户想使用列表 ADT 来插入 Kevin 和 John 来列出某些任务。
//list.h
typedef struct list_t list_t;
list_t* list_create(/*might have some arguments*/);
所以客户端代码将是
#include "employee.h"
#include "list.h"
employee_t* Kevin = employee_create("Facebook", "Marketing", "Sales");
employee_t* John = employee_create("Microsoft", "R&D", "Engineer");
list_t* employee = list_create(/*might have some arguments*/);
list_insert(employee, Kevin);
list_insert(employee, John);
employee_free(Kevin);
employee_free(John);
list_print(employee); //Oops! How to print structure that you can't see?
由于employee被不透明指针封装,list无法复制。
list的ADT怎么写和实现?
【问题讨论】:
-
为什么不将
void*存储在您的列表中? -
您的问题不清楚:“如何编写此列表 ADT 和实现?” 阻碍您编写此列表 ADT 和实现的问题是什么?
-
这种类型取决于
list_t的通用程度以及您是否想以老式方式(空指针)或现代方式(某种方式的预处理器处理所有支持类型)。此处不同方式的类似用例示例:stackoverflow.com/a/69379395/584518 -
为什么不
list_insert (sizeof employee_t, Kevin)传递要分配的存储大小和指向该存储的指针,以及malloc()、memcpy()例如Kevin分配给新块并将新块分配给列表的void *指针数据成员?您仍然需要编写有关如何将printf、remove、query与employee_t类型相关的函数,但您的列表会起作用。这是 C 和类型的 Catch-22。虽然您可以创建一个通用列表并将 function-pointer 作为参数传递给列表操作,但您也可以只为employee_t编写一个列表。 -
C 中的主要问题是制作数据硬拷贝的 ADT 不是很明智,因为您要么必须提供
void*以及大小和/或某些类型标志枚举。或者你必须提供一些带有函数指针的回调接口。因此,实现明智的 ADT 的一种方法是简单地不制作任何数据的硬拷贝,而是将其留给调用者。无论如何,像链表这样带有碎片堆分配的方法已经过时了,因为它在 任何 8 位到 64 位的主流计算机上都不是很有效。
标签: c encapsulation generic-list abstract-data-type opaque-pointers