2010-10-04 17 views
28

¿Qué es un "valor opaco" en C++?¿Qué es un valor opaco?

+5

¿Algún otro contexto? – DevSolar

+0

¿por qué esta pregunta está etiquetada como agnóstica del lenguaje? – JPCF

+0

@JPCF: Porque los objetos opacos son comunes en muchos idiomas. –

Respuesta

28

Un ejemplo para un valor opaco es FILE (en la librería C):

#include <stdio.h> 

int main() 
{ 
    FILE * fh = fopen("foo", "r"); 
    if (fh != NULL) 
    { 
     fprintf(fh, "Hello"); 
     fclose(fh); 
    } 
    return 0; 
} 

Se obtiene un puntero FILE de fopen(), y lo utiliza como parámetro para otras funciones, pero nunca se molestan con lo en realidad apunta a a.

+2

Que en realidad es un puntero no es importante; los punteros opacos son solo valores opacos que resultan ser punteros. –

+2

En realidad, opaque tiene poco que ver con si usted _muchas_ con lo que apunta, esa es una opción del usuario. Un verdadero puntero opaco _revela_ sin detalles. Si miras dentro de stdio.h y la estructura está definida, entonces FILE no es opaco. – paxdiablo

+1

@paxdiablo: Lingüística. Ninguna operación necesita acceder realmente al * valor * de un 'ARCHIVO', simplemente lo pasa por alto. Si no puede entender su contenido en los encabezados, puede seguir con la ingeniería inversa, pero no tiene que hacerlo, porque su estructura no tiene importancia. El implementador de la biblioteca podría cambiar sus partes internas sin previo aviso, y no debería hacer una diferencia. (A menos que, por supuesto, * hayas penetrado * en su estructura interna). No confundas la facilidad de acceso con la accesibilidad. Los miembros de datos "privados" de C++ tampoco son "invisibles" ... – DevSolar

2

Es similar a opaque pointer - un valor que no almacena datos; su código podría interpretar o proporcionar acceso a los datos, pero solo identifica algunos otros datos. Un ejemplo típico es un identificador de Win32 como el identificador de mapa de bits HBITMAP; solo puede pasarlo a funciones relevantes, pero no puede hacer nada directamente con el mapa de bits subyacente.

+0

@MatteoItalia sharptooth DIJO que HBITMAP es un puntero opaco; no hay ningún reclamo aquí que contenga el mapa de bits en sí mismo. –

+0

@JimBalter: o leí mal, o fue editado después de mi comentario, o pensé en algo completamente diferente. Honestamente, después de cuatro años no puedo recordar. Eliminaré mi comentario de todos modos ya que ya no es relevante (si alguna vez lo fue). –

2

ARCHIVO * es un buen ejemplo de un valor opaco. No lo usas directamente; es un solo "blob" que no puedes interpretar o manipular. En su lugar, utiliza un conjunto de funciones (fopen, fwrite, fprintf, etc.) que saben cómo manipularlo.

Ser opaco de esta manera es común en muchas situaciones (y en muchas API) donde tienes un mango "mágico": una caja negra.

1

de Wikipedia

En informática, un tipo de datos opaco es un tipo de datos que es incompletamente definida en una interfaz, por lo que sus valores sólo pueden ser manipulado llamando a subrutinas que tienen acceso a la falta información. La representación concreta del tipo está oculta en sus usuarios

Los ejemplos típicos de tipos de datos opacos incluyen identificadores para los recursos proporcionados por un sistema operativo al software de aplicación.

Algunos lenguajes, como C, permiten la declaración de registros opacos (structs), cuyo tamaño y campos están ocultos para el cliente. La única cosa que puede hacer el cliente con un objeto de ese tipo es tomar su dirección de memoria, para producir un puntero opaco.

Si la información proporcionada por la interfaz es suficiente para determinar el tamaño del tipo, los clientes pueden declarar variables, campos, y arreglos de ese tipo, asignar sus valores, y posiblemente comparar ellos por la igualdad. Este suele ser el caso para punteros opacos.

32

"Opaco" está definido, en inglés, como "no se puede ver a través de; no es transparente". En Informática, esto significa un valor que no revela detalles distintos del tipo del valor en sí.

personas a menudo usan el tipo C FILE como el ejemplo clásico, pero a menudo esto es no opaco - los detalles se revelan en stdio.h para que cualquiera pueda ver y que se basan simplemente en el usuario del tipo de no jugar con los elementos internos . Eso está bien siempre y cuando la gente se adhiera a las reglas, solo pase tales valores a funciones como fread() y fclose(), pero el problema con la revelación de información es que las personas algunas veces (neciamente) comienzan a confiar en ella.

Por ejemplo, glibc publica su FILE estructura (como struct _IO_FILE) en libio.h de modo que el tipo no es técnicamente opaco.

Tenga en cuenta que parte de la definición en la parte delantera: "no puede" en lugar de "no está dispuesto". Opacity requiere que se oculte la información en lugar de promulgar un "acuerdo de caballeros" para no usarla.

Los indicadores opacos, hechos correctamente, deben revelar no información que no sea el nombre del tipo en sí y puede implementarlo en C con relativa facilidad. Considere el siguiente archivo de cabecera prog2.h para la obtención y la liberación de xyzzy objetos:

struct xyzzy; 
struct xyzzy *xyzzyOpen (void); 
void xyzzyClose (struct xyzzy *fh); 

todo esto es que los clientes del código de ver, un tipo incompleto struct xyzzy y algunas funciones para asignar y liberar objetos de ese tipo (que no lo hacen ve a ver prog2.c detallado a continuación). Tenga en cuenta que punteros a un tipo incompleto están bien, pero no puede instanciar un objeto de ese tipo ya que no conoce sus partes internas. Por lo que el código:

struct xyzzy myvar; 

causaría un error en la línea de:

prog1.c: In function ‘main’: 
prog1.c:3:15: error: storage size of 'myvar' isn't known 

Ahora puede usar felizmente aquellas funciones de un programa prog1.csin conocer los detalles internos de la estructura:

#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; 
} 

Y el aplicación de las llamadas, prog2.c, en realidad controla y sabe los componentes internos, por lo que puede usarlos con bastante libertad:

#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); 
} 

Los printf llamadas están allí simplemente para demostrar que puede utilizar los componentes internos, y es probable que querría añadir chequeo de el valor de retorno de malloc en código listo para producción pero que no es relevante para el propósito de este ejemplo.

Al compilar prog1.c y prog2.c en un único archivo ejecutable y ejecutarlo, la salida es:

xyzzyOpen payload = 42 
xyzzyOpen payload = 43 
xyzzyOpen payload = 44 
xyzzyClose payload = 42 
xyzzyClose payload = 44 
xyzzyClose payload = 43 

como era de esperar de la función principal.

+6

Subimos de categoría a pesar de nuestro desacuerdo, porque cuando lo ponemos en su lugar, * resalta * un ángulo interesante sobre el tema. El estar en desacuerdo con su necesidad no significa que no pueda respaldar una buena presentación de sus méritos. ;-) Sin resentimientos, y pasar un buen rato. – DevSolar

+6

@DevSolar, si todos estuviéramos de acuerdo, me aburriría sin sentido :-) Saludos. – paxdiablo

+1

Interesante comentario: si tengo acceso a la fuente de 'prog2.c', I * would * podrá acceder a las partes internas de la estructura. ¿La estructura sigue siendo "opaca" según tu definición, entonces? ¿O la verdadera opacidad requiere un modelo de programación de fuente cerrada? (Solo tirando de tu pierna, tratando de apuntar a mi definición de "opacidad" mirando la documentación, no el origen del encabezado. ;-)) – DevSolar

Cuestiones relacionadas