我找到了一个 foo.h 文件:
typedef STRUCT_s STRUCT;
STRUCT *foo();
和 foo.c 文件:
#include "i_foo.h"
struct STRUCT_s{
//...
};
#define STRUCT struct STRUCT_s
STRUCT *foo()
{
STRUCT *s;
//...
return s;
}
这是隐藏C中结构定义的常用方法吗?如果是,我想知道,如果结构未在标题中声明,客户端应该如何使用它?
答案 0 :(得分:3)
用户通过这种方式无法实例化结构,只能看到此类型的对象作为指针。因此,所有构造函数和方法,getter,setter等对用户来说都是模糊的,应该在库源中定义。
一个明显的额外后果是,如果您更改结构,用户不必更改代码中的所有用途来初始化新字段或注释掉已解散的字段。既然没有,那就没有了。结构的内部私有结构是完全隐藏的。
答案 1 :(得分:3)
这是在C中隐藏结构定义的常用方法。客户端不应该直接使用结构。他必须只使用接口中提出的函数来与数据交互:实例化,设置或获取值,在其上启动操作,....
通过这种方式,实现对客户端完全隐藏。因此客户端不受实现变化的约束。根据界面没有变化,图书馆可以随心所欲地发展而不会打扰客户端。
答案 2 :(得分:2)
是的,这是声明抽象数据类型(ATD)的常用方法。 ADT仅通过其接口使用,该接口由头文件中声明的函数表示。客户端不直接访问这些字段。为所有导出的标识符添加前缀也是一个好主意。这可以避免名称冲突,并清楚地表明导入的标识符的来源。
示例:
Stacks.h
typedef struct Stacks_StackDesc *Stacks_Stack;
Stack Stacks_New(void);
void Stacks_Push(int x, Stacks_Stack s);
void Stacks_Pop(Stacks_Stack s, int *top);
Stacks.c
#include "Stacks.h"
struct Stacks_StackDesc {
...
};
Stack Stacks_New(void)
{
...
}
void Stacks_Push(int x, Stacks_Stack s)
{
...
}
void Stacks_Pop(Stacks_Stack s, int *top)
{
...
}