“不透明”在英语中的定义是“不能被看穿;不透明”。在计算机科学中,这意味着除了值本身的类型之外不显示任何细节的值。
人们经常使用C型FILE
作为经典的例子,但通常这是not不透明 - 细节显示在stdio.h
任何人都可以看到,他们只是依赖该类型的用户不要摆弄内部结构。只要人们遵守规则,只将这些值传递给诸如fread()
and fclose()
但披露信息的问题在于人们有时(愚蠢地)开始依赖它。
例如,glibc
发布其FILE
结构(如struct _IO_FILE
) in libio.h
因此该类型在技术上并不是不透明的。
注意前面的部分定义:“不能”而不是“不愿意”。不透明性要求隐藏信息,而不仅仅是制定不使用信息的“君子协定”。
正确完成的不透明指针应该会显示no除了类型名称本身之外的信息,您可以相对轻松地在 C 中实现它。考虑以下头文件prog2.h
用于获取和释放xyzzy
对象:
struct xyzzy;
struct xyzzy *xyzzyOpen (void);
void xyzzyClose (struct xyzzy *fh);
这就是代码的客户端看到的全部内容,一个不完整的类型struct xyzzy
以及一些分配和释放该类型对象的函数(他们看不到prog2.c
详细如下)。注意pointers不完整的类型很好,但是您无法实例化该类型的对象,因为您不知道其内部结构。所以代码:
struct xyzzy myvar;
会导致如下错误:
prog1.c: In function ‘main’:
prog1.c:3:15: error: storage size of 'myvar' isn't known
现在您可以非常愉快地使用程序中的这些功能prog1.c
without了解结构的内部结构:
#include "prog2.h"
int main (void) {
//struct xyzzy myvar; // will error
struct xyzzy *num1 = xyzzyOpen();
struct xyzzy *num2 = xyzzyOpen();
struct xyzzy *num3 = xyzzyOpen();
xyzzyClose (num1);
xyzzyClose (num3); // these two intentionally
xyzzyClose (num2); // reversed.
return 0;
}
And the 执行的通话中,prog2.c
,实际上控制和knows内部结构,因此可以非常自由地使用它们:
#include <stdio.h>
#include <stdlib.h>
#include "prog2.h"
struct xyzzy { int payload; };
static int payloadVal = 42;
struct xyzzy *xyzzyOpen (void) {
struct xyzzy *plugh = malloc (sizeof (struct xyzzy));
plugh->payload = payloadVal++;
printf ("xyzzyOpen payload = %d\n", plugh->payload);
return plugh;
}
void xyzzyClose (struct xyzzy *plugh) {
printf ("xyzzyClose payload = %d\n", plugh->payload);
free (plugh);
}
The printf
调用只是为了表明它可以使用内部结构,并且您可能希望添加对返回值的检查malloc
在生产就绪代码中,但这与本示例的目的无关。
当你编译时prog1.c
and prog2.c
进入单个可执行文件并运行它,输出为:
xyzzyOpen payload = 42
xyzzyOpen payload = 43
xyzzyOpen payload = 44
xyzzyClose payload = 42
xyzzyClose payload = 44
xyzzyClose payload = 43
正如您对 main 函数的期望。