C ++中的“不透明值”是什么?
答案 0 :(得分:41)
“不透明”在英语中定义为“无法透视;不透明”。在计算机科学中,这意味着一个值,除了价值本身的类型之外,没有任何细节。
人们经常使用C类型FILE
作为经典示例,但通常不不透明 - 详细信息在stdio.h
中显示,任何人都可以看到,他们只是依赖对类型的用户不要捏造内部。只要人们遵守规则,只将这些值传递给fread()
和fclose()
这样的函数,那就没问题,但揭示信息的问题在于人们有时(愚蠢地)开始依赖它。
例如,glibc
在FILE
中发布其struct _IO_FILE
结构(libio.h
),因此该类型在技术上不透明。
请注意前面部分定义:“不能”而不是“不愿意”。不透明度要求隐藏信息而不是仅仅制定一个“绅士的同意”不使用它。
不正确的不透明指针应该显示除了类型名称本身之外的 no 信息,你可以相对容易地在C中实现它。请考虑以下头文件prog2.h
以获取和释放xyzzy
个对象:
struct xyzzy;
struct xyzzy *xyzzyOpen (void);
void xyzzyClose (struct xyzzy *fh);
这是代码的客户端看到的所有内容,一个不完整的类型struct xyzzy
以及一些用于分配和释放该类型对象的函数(他们无法查看下面详述的prog2.c
)。请注意,指针到一个不完整的类型是可以的,但你不能实例化那种类型的对象,因为你不知道它的内部。所以代码:
struct xyzzy myvar;
会导致错误:
prog1.c: In function ‘main’:
prog1.c:3:15: error: storage size of 'myvar' isn't known
现在,您可以非常高兴地使用程序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;
}
调用的实现,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);
}
printf
调用只是为了表明它可以使用内部结构,并且您可能希望在生产就绪代码中添加来自malloc
的返回值的检查,但这不相关为了这个例子的目的。
将prog1.c
和prog2.c
编译成单个可执行文件并运行它时,输出为:
xyzzyOpen payload = 42
xyzzyOpen payload = 43
xyzzyOpen payload = 44
xyzzyClose payload = 42
xyzzyClose payload = 44
xyzzyClose payload = 43
正如您对主要功能所期望的那样。
答案 1 :(得分:31)
不透明值的示例是FILE
(来自C库):
#include <stdio.h>
int main()
{
FILE * fh = fopen( "foo", "r" );
if ( fh != NULL )
{
fprintf( fh, "Hello" );
fclose( fh );
}
return 0;
}
你从FILE
得到一个fopen()
指针,并将其用作其他函数的参数,但你从不打扰它实际指向到的内容。
答案 2 :(得分:2)
这类似于opaque pointer - 一个值,它不存储您的代码可以解释或提供数据访问的数据,但只识别其他一些数据。一个典型的例子是Win32句柄,如HBITMAP
位图句柄 - 你只能将它传递给相关的函数,但你不能直接对底层的位图做任何事情。
答案 3 :(得分:2)
FILE *是不透明值的一个很好的例子。你不直接使用它;它是一个你无法解释或操纵的“blob”。相反,你使用一组知道如何操纵它的函数(fopen,fwrite,fprintf等)。
以这种方式不透明在许多情况下(以及在许多API中)都是常见的,在这种情况下你有一个“神奇”的句柄:黑盒子。
答案 4 :(得分:1)
在计算机科学中,不透明数据类型是一种数据类型 在接口中未完全定义,因此其值只能是 通过调用有权访问缺失的子例程来操纵 信息。该类型的具体表示是隐藏的 其用户
不透明数据类型的典型示例包括资源句柄 由操作系统提供给应用软件。
某些语言(如C)允许声明不透明记录 (结构),其大小和字段对客户端隐藏。唯一的 客户端可以对这种类型的对象做的事情是采取 它的内存地址,用于生成不透明的指针。
如果界面提供的信息足够 确定类型的大小,然后客户端可以声明变量,字段, 和该类型的数组,分配它们的值,并可能进行比较 他们是平等的。这通常是不透明指针的情况。