what example ejemplo define cppreference c oop struct compiler-errors data-hiding

example - typedef struct c ejemplo



Ocultando la definiciĆ³n de C struct (4)

Las otras respuestas cubren tu problema bastante bien. Sin embargo, permítanme agregarles y responder a su último comentario:

Estoy obteniendo un error de compilación: en public.h: redefinición de typedef PRIVATE _...

Si bien el error se explica por sí mismo, probablemente sea menos claro por qué está sucediendo eso. Considere lo que sucede cuando incluye public.h:

#include "struct.h" #include "func.h" typedef struct _my_private_struct PRIVATE_;

Si rastrea esto y expande completamente el preprocesador, esto es lo que obtendrá:

// struct.h struct _my_private_struct { int i; }; // func.h typedef struct _my_private_struct PRIVATE_; extern PRIVATE_ * get_new(int); // public.h typedef struct _my_private_struct PRIVATE_;

Ahora debería ser obvio por qué estás teniendo problemas. Sin el typedef en func.h, tu get_new prototype falla porque aún no se ha visto PRIVATE . OTOH, si dejas el typedef, lo has definido dos veces.

Además, parece que estás tratando de mantener esa estructura privada de otros códigos y módulos. Incluso si arreglas los errores de compilación, realmente no has logrado esa encapsulación. Considera esto:

int main() { PRIVATE_ *p = get_new(2); p->i = 1337; // HAHA, I just modified your private i. // what are you going to do about it? }

Si desea privacidad de datos en C, considere un diseño de puntero opaco. Recomiendo reestructurar su fuente de esta manera:

// public.h #ifndef PUBLIC_H_ #define PUBLIC_H_ #include "func.h" #endif

// func.h #ifndef FUNC_H_ #define FUNC_H_ struct PRIVATE_NOT_ACCESSIBLE; typedef struct PRIVATE_NOT_ACCESSIBLE myint_t; // declare your struct methods here myint_t* get_new(int); // .. #endif

// func.c #include <stdlib.h> #include "func.h" // define this only with functions // that''s suppose to work with its internal data struct PRIVATE_NOT_ACCESSIBLE { int i; }; myint_t * get_new(int i) { // ... }

Ahora si intentas esto:

#include "public.h" int main() { myint_t *p = get_new(2); p->i = 1337; // Aw, doesn''t work anymore :( }

Editar: para responder el comentario de OP a continuación.

Si tiene métodos de struct privados implementados en más de una unidad de compilación, puede hacerlo funcionar moviendo la definición de private a un encabezado dedicado:

// func_implementation.h #include "func.h" struct PRIVATE_NOT_ACCESSIBLE { int i; }; // internal methods, helper functions you don''t want exposed should go here too. // eg. void helper_method(myint_t *);

Los archivos fuente que implementan su ''objeto'' privado de estructura incluirán ''func_implementation.h''. El código de cliente externo que usa privado incluirá solamente ''func.h''.

He aquí mi arreglo:

En public.h:

#ifndef PUBLIC_H_ #define PUBLIC_H_ #include "func.h" /*extern typedef struct _my_private_struct PRIVATE_;*/ typedef struct _my_private_struct PRIVATE_; /* Thanks to larsmans and Simon Richter */ #endif

En struct.h

#ifndef STRUCT_H_ #define STRUCT_H_ struct _my_private_struct { int i; }; #endif

En func.h:

#ifndef FUNC_H_ #define FUNC_H_ #include "struct.h" /* typedef struct _my_private_struct PRIVATE_; */ extern PRIVATE_ * get_new(int); #endif

En func.c:

#include <stdlib.h> #include "func.h" PRIVATE_ * get_new(int i) { PRIVATE_ *p = (PRIVATE_ *) malloc(sizeof(PRIVATE_)); if (p == NULL) return NULL; p->i = i; return p; }

En main.c:

#include "public.h" int main(int argc, char ** argv) { PRIVATE_ *p = get_new(2); return 0; }

Cuando compilo esos archivos con GCC obtengo este error:

ANTIGUO ERROR COMPILE

múltiples clases de almacenamiento en especificadores de declaración

COMPILAR EL ERROR DESPUÉS DE EDITAR

esperado ''='', '','', '';'', ''asm'' o ''__attribute__'' antes de ''*'' token

¿Puede alguien ayudarme / explicarme por qué estoy recibiendo esto y cómo solucionarlo?


Hay un '';'' falta después de typedef.

EDITAR:

struct _my_private_struct {...};

No use nombres con un subrayado inicial. Están reservados para el idioma o la implementación.


La sintaxis actual es incorrecta, necesita poner un punto y coma después de los tiposdefs y las estructuras.


  • Debe finalizar una instrucción typedef con a ;
  • extern typedef no tiene sentido, solo haz un typedef .