2010-03-26 16 views
14

Estoy desarrollando una biblioteca simple en C, para mi propio uso personal y para algunos amigos.¿Hay alguna solución para hacer que un miembro de la estructura sea de alguna manera "privado" en C?

Actualmente estoy teniendo una estructura en C con algunos miembros que de alguna manera deberían estar ocultos del resto de la aplicación, ya que su uso es solo interno. Modificar por accidente uno de estos miembros probablemente hará que la biblioteca se "vuelva loca".

¿Hay alguna 'solución' para ocultar esos miembros para que no puedan ser accesibles?

+0

Parece que la idea es mantener la estructura 'oculta' en el archivo .c, mientras se declara la interfaz de acceso en el archivo .h. ¡Espero hacerlo bien! –

Respuesta

15

siguiendo la técnica habitual es la siguiente:

/* foo.h */ 
typedef struct Foo Foo; 

Foo *foo_create(...); 

void foo_bark(Foo* foo, double loudness); 

/* foo.c */ 
struct Foo { 
    int private_var; 
}; 

Puede ocultar parcialmente los miembros de datos mediante la definición de Foo en la cabecera y FooPrivate en el archivo .c así:

struct FooPrivate { 
    Foo public_stuff; 
    int private_var; 
} 

Pero entonces su aplicación tiene para enviar y recibir mensajes entre Foo y FooPrivate, que considero que es un PITA real, y es una carga de mantenimiento si cambias de opinión más adelante y quieres hacer algo en privado. A menos que quiera extraer hasta el último ciclo de CPU del código, solo use las funciones de acceso.

+3

Puede ser más específico. :) –

+1

@nomemory, proporciona solo una interfaz para actualizar campos específicos, no revela la estructura. Como las funciones foo_create y foo_bark, por ejemplo. –

+1

Esto oculta los * enteros * contenidos de la 'estructura', no campos específicos, por lo que se necesitarán accesos. –

2

Marcelo Cantos ya le ha dado la respuesta. Para obtener información más detallada, debe ver cómo la estructura de archivos está efectivamente oculta en la mayoría de las bibliotecas de Uderlying.

Habría notado que la estructura FILE en sí nunca está disponible para el usuario, solo las interfaces y un Opaque FILE * están disponibles para nosotros.

1

Básicamente, la idea es cambiar el nombre de las variables de la estructura con algo como un hash y escribir funciones (que ordenarían los métodos miméticos en lenguajes OO) para acceder a ellas. Idealmente, debería tener punteros de función para esas funciones en su estructura para que no tenga que llamar a una función externa y pasarla a la estructura de los miembros que desea agregar. Sin embargo, se desconoce que la sintaxis del puntero a la función sea la más bonita. Un simple ejemplo que puede aclarar lo que se ha dicho antes por Marcelo:

struct Car { 
    int _size; 
    char _colour[10]; 

}; 

typedef struct Car Car; 


int main (int argc, char **argv) { 
    Car *myCar= malloc(sizeof(Car)); 
    myCar->_size=5; /* accessing it directly just to set up a value, you shold have an 
         accessor function really */ 

    printf("car size is: %i \n",getCarSize(myCar)); 
    free(myCar); 
} 




int getCarSize(Car *myCar) { 
    return myCar->_size; 
} 
+0

Es posible que el código pase alrededor de un puntero a una 'struct foo' sin saber nada sobre el contenido de la estructura, pero la creación de una variable de tipo 'struct foo' requiere tener sus contenidos definidos. ¿Se define el tipo de juego de palabras entre diferentes tipos de unión si el tamaño y la alineación de ambas uniones están restringidos por el mismo tipo (por ejemplo, un 'largo largo [4]')? – supercat

1

Estoy de acuerdo con Marcelo Cantos, pero también sugieren la simple adición de un puntero dentro de la estructura de "público", que apunta a los contenidos "privadas", es decir:

/* foo.h */ 
typedef struct Bar Bar; 
typedef struct Foo 
{ 
    int public; 
    Bar* private; 
} Foo; 

Foo *foo_create(...); 

void foo_bark(Foo* foo, double loudness); 

/* foo.c */ 
struct Bar 
{ 
    int private_var; 
}; 

Este enfoque es algo así como el "pimpl" ideom. El enfoque más simple hasta ahora es hacer lo que sugirió Marcelo Cantos.

+0

Gracias, parece que C puede soportar algunas características "oop" con un pequeño esfuerzo por parte del programador :). –

Cuestiones relacionadas