C中的opaque(抽象)数据类型

文件api.h

#include  #ifndef API #define API struct trytag; typedef struct trytag try; void trial (try *); #endif 

文件core.h

 #ifndef CORE #define CORE struct trytag { int a; int b; }; #endif 

文件func.c

 #include "api.h" #include "core.h" void trial (try *tryvar) { tryvar->a = 1; tryvar->b = 2; } 

文件main.c

 #include "api.h" int main () { try s_tryvar; trial(&s_tryvar); printf("a = %d\nb = %d\n", s_tryvar.a, s_tryvar.b); } 

当我编译时,我得到:

 main.c:5: error: storage size of 's_tryvar' isn't known 

如果我在main.c包含core.h ,则不会出现此错误,因为在core.h定义了core.h 。 但我希望结构try隐藏到main.c – 它不应该知道try结构的成员。 我错过了什么?

我不认为你想做的事情是可能的。 编译器需要知道编译main.ctry结构有多大。 如果你真的希望它是不透明的,那么创建一个通用的指针类型,而不是直接在main()中声明变量,而是使用alloc_try()free_try()函数来处理创建和删除。

像这样的东西:

api.h:

 #ifndef API #define API struct trytag; typedef struct trytag try; try *alloc_try(void); void free_try(try *); int try_a(try *); int try_b(try *); void trial (try *); #endif 

core.h:

 #ifndef CORE #define CORE struct trytag { int a; int b; }; #endif 

func.c:

 #include "api.h" #include "core.h" #include  try *alloc_try(void) { return malloc(sizeof(struct trytag)); } void free_try(try *t) { free(t); } int try_a(try *t) { return t->a; } int try_b(try *t) { return t->b; } void trial(try *t) { t->a = 1; t->b = 2; } 

main.c中:

 #include  #include "api.h" int main() { try *s_tryvar = alloc_try(); trial(s_tryvar); printf("a = %d\nb = %d\n", try_a(s_tryvar), try_b(s_tryvar)); free_try(s_tryvar); } 

想想不透明的FILE结构如何在C中工作。你只使用指针,你需要一个像fopen()这样的函数来创建一个实例,并且需要一个像fclose()这样的函数来处理它。

问题出在main.c中,编译器还没有看到struct try的定义。 因此,编译器仅限于使用指向struct try指针。

您要做的是为您的API添加两个新function:

 try *create_try(); void *destroy_try(try *t); 

这些函数将分别调用malloc和free。

如果您不希望将结构限制为仅允许在堆上,则您将不得不放弃使其不透明。

有一种方法可以做一些技术上并不完全符合您要求的方法,但应该起到保持结构不透明同样的目的,同时支持非堆分配。

在api.h中,您声明了一个不透明的结构如下:

 struct trytag_opaque { char data[sizeof(int)*2]; }; 

如果你想比它更不透明,你可以计算任何支持平台所需的最大结构大小,并使用:

 struct trytag_opaque { char data[MAX_TRYTAG_SIZE]; }; 

然后你的api.h函数声明如下:

 int try_a(struct trytag_opaque *t) 

你的function代码如下:

 int try_a(struct trytag_opaque *t_opaque) { trytag *t = (trytag *)t_opaque; ... } 

你的main.c看起来像:

 #include "api.h" int main() { struct trytag_opaque t; ... try_a(&t); ... }