Menu
CoddyTech

Definición de structs opacos

Parte de la sección Programación Orientada a Objetos del Journey de C de Coddy. Lección 18 de 61.

Ahora que entiendes el concepto de punteros opacos, veamos cómo completar el patrón. El encabezado declara que existe un tipo, pero el archivo fuente es donde defines lo que contiene realmente.

Aquí tienes la configuración completa. Primero, el encabezado con solo la declaración anticipada:

// counter.h
#ifndef COUNTER_H
#define COUNTER_H

typedef struct Counter Counter;  // Tipo incompleto

Counter *create_counter(int start);
void free_counter(Counter *c);

#endif

Después, el archivo de origen contiene la definición real de la estructura:

// counter.c
#include "counter.h"
#include <stdlib.h>

struct Counter {
    int value;      // ¡Oculto desde fuera!
    int step;
};

Counter *create_counter(int start) {
    Counter *c = malloc(sizeof(Counter));
    c->value = start;
    c->step = 1;
    return c;
}

void free_counter(Counter *c) {
    free(c);
}

El punto clave: struct Counter { ... } aparece solo en el archivo .c. Cualquier archivo que incluya counter.h sabe que Counter existe, pero no puede ver value ni step. Intentar escribir c->value en main.c provocaría un error del compilador: los miembros son realmente invisibles.

Esta separación es la base de la encapsulación en C. El siguiente paso es proporcionar acceso controlado mediante funciones getter y setter.

challenge icon

Desafío

Fácil

Vamos a crear un módulo Timer que demuestra el patrón de puntero opaco. Practicarás cómo ocultar la definición de la estructura dentro del archivo fuente, haciendo que sus miembros internos sean completamente invisibles para cualquier código que use tu módulo.

Crearás tres archivos:

  • timer.h: Esta es tu interfaz pública. Declara un tipo opaco Timer usando solo una declaración adelantada: ¡aquí no va el cuerpo de la estructura! Declara también dos funciones: create_timer (recibe un entero que representa los segundos y devuelve un puntero a Timer) y free_timer (recibe un puntero a Timer y libera sus recursos). Usa guardas de inclusión con el símbolo TIMER_H.
  • timer.c: Aquí está el secreto. Define la struct Timer real con dos miembros ocultos: int seconds y int running (usa 1 para indicar que está en funcionamiento y 0 para indicar que está detenido). Implementa el constructor para asignar memoria a la estructura, inicializar seconds con el valor proporcionado y establecer running en 1. Implementa el destructor para liberar la memoria.
  • main.c: Usa tu módulo Timer para crear un temporizador y confirmar que se creó correctamente. Como los miembros de la estructura están ocultos, no puedes acceder a ellos directamente. ¡Ese es precisamente el objetivo! Simplemente imprime un mensaje que confirme la creación, luego libera el temporizador e imprime un mensaje de limpieza.

Recibirás una entrada: el número de segundos (un entero) con el que se inicializará el temporizador.

En tu archivo principal, crea un temporizador con el valor de segundos proporcionado. Imprime un mensaje de creación, luego libera el temporizador e imprime una confirmación.

Imprime la salida con este formato:

Timer created
Timer freed

La idea clave es que main.c puede trabajar con punteros a Timer, pero no tiene forma de acceder directamente a seconds ni a running. Intentar escribir t->seconds en main.c provocaría un error del compilador porque el cuerpo de la estructura solo está definido en timer.c. Esto es encapsulación de verdad: los detalles de implementación están completamente ocultos para quienes usan tu módulo.

Pruébalo tú mismo

#include <stdio.h>
#include "timer.h"

int main() {
    int seconds;
    scanf("%d", &seconds);
    
    // TODO: Crea un temporizador con el valor de segundos proporcionado
    
    // TODO: Imprime "Timer created"
    
    // TODO: Libera el temporizador
    
    // TODO: Imprime "Timer freed"
    
    return 0;
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de C online