pax*_*blo 42
"不透明"用英语定义为"不能透视;不透明".在计算机科学中,这意味着一个值,除了值本身的类型之外,没有显示任何细节.
人们经常使用C类型FILE作为经典示例,但通常这不是不透明的 - stdio.h任何人都可以看到细节,他们只是依靠类型的用户来摆弄内部.只要人们遵守规则,只将这些价值传递给类似的功能,那就没问题了fread(),fclose()但是泄露信息的问题是人们有时(愚蠢地)开始依赖它.
例如,glibc发布其FILE结构(as struct _IO_FILE),libio.h以便该类型在技术上不是不透明的.
请注意前面部分定义:"不能"而不是"不愿意".不透明度要求隐藏信息,而不是仅仅颁布"绅士协议"而不使用它.
正确完成的不透明指针应该不会显示除类型名称本身之外的任何信息,您可以相对容易地在C中实现它.考虑以下prog2.h用于获取和释放xyzzy对象的头文件:
struct xyzzy;
struct xyzzy *xyzzyOpen (void);
void xyzzyClose (struct xyzzy *fh);
Run Code Online (Sandbox Code Playgroud)
这就是代码的客户端看到的所有内容,一个不完整的类型struct xyzzy以及一些用于分配和释放该类型对象的函数(它们不会prog2.c在下面详细介绍).请注意,指向不完整类型的指针很好但是您无法实例化该类型的对象,因为您不知道其内部.所以代码:
struct xyzzy myvar;
Run Code Online (Sandbox Code Playgroud)
会导致错误:
prog1.c: In function ‘main’:
prog1.c:3:15: error: storage size of 'myvar' isn't known
Run Code Online (Sandbox Code Playgroud)
现在,您可以非常愉快地使用程序中的这些函数,prog1.c 而无需了解结构的内部结构:
#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;
}
Run Code Online (Sandbox Code Playgroud)
并且调用的实现prog2.c,实际上控制并知道内部,因此可以非常自由地使用它们:
#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);
}
Run Code Online (Sandbox Code Playgroud)
该printf呼叫在那里只是为了表明它可以使用内部,你可能会想从添加的返回值的检查malloc在生产就绪代码,但是这是不相关的这个例子的目的.
当您编译prog1.c并prog2.c运行单个可执行文件并运行它时,输出为:
xyzzyOpen payload = 42
xyzzyOpen payload = 43
xyzzyOpen payload = 44
xyzzyClose payload = 42
xyzzyClose payload = 44
xyzzyClose payload = 43
Run Code Online (Sandbox Code Playgroud)
正如你对主要功能所期望的那样.
Dev*_*lar 33
不透明值的一个例子是FILE(来自C库):
#include <stdio.h>
int main()
{
FILE * fh = fopen( "foo", "r" );
if ( fh != NULL )
{
fprintf( fh, "Hello" );
fclose( fh );
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
你得到一个FILE指针fopen(),并将其用作其他函数的参数,但你从不打扰它实际指向的内容.
| 归档时间: |
|
| 查看次数: |
15267 次 |
| 最近记录: |