Menu
Coddy logo textTech

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 los punteros opacos, veamos cómo completar el patrón. El encabezado declara que existe un tipo, pero el archivo fuente es donde defines qué hay realmente dentro.

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 fuente 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 únicamente 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 verdaderamente 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

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

Crearás tres archivos:

  • timer.h: Esta es tu interfaz pública. Declara un tipo opaco Timer usando únicamente una declaración anticipada: ¡no incluyas aquí 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 realiza la limpieza). Usa protecciones de inclusión con el símbolo TIMER_H.
  • timer.c: Aquí vive el secreto. Define la struct Timer real con dos miembros ocultos: int seconds y int running (usa 1 para indicar que está en ejecución y 0 para indicar que está detenido). Implementa tu constructor para reservar memoria para 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. ¡Este es precisamente el objetivo! Simplemente imprime un mensaje que confirme la creación, después 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, después libera el temporizador e imprime una confirmación.

Imprime la salida con este formato:

Timer created
Timer freed

La idea clave aquí 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 una encapsulación verdadera: los detalles de implementación están completamente ocultos para los usuarios de 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: Print "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