Menu
Coddy logo textTech

Punteros a funciones en estructuras

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

Hasta ahora, hemos usado punteros de function como variables independientes o los hemos pasado como argumentos. El siguiente paso hacia el polimorfismo es insertar un puntero de function directamente dentro de una estructura, dotando a la estructura de su propio comportamiento.

Cuando una estructura contiene un puntero a función, cada instancia puede contener una función diferente. Esto significa que dos objetos del mismo tipo pueden comportarse de manera diferente cuando llamas a su puntero a función:

typedef void (*PrintFunc)(const char*);

typedef struct {
    const char* name;
    PrintFunc print;  // Puntero a función como miembro
} Printer;

La estructura Printer ahora tiene dos miembros: datos (name) y comportamiento (print). Para usarla, asignas una función al pointer durante la inicialización:

void loud_print(const char* msg) {
    printf("!!! %s !!!\n", msg);
}

int main() {
    Printer p;
    p.name = "Alert";
    p.print = loud_print;
    
    p.print("Hello");  // Salida: !!! Hello !!!
    return 0;
}

Observa cómo llamamos a la función a través de la estructura: p.print("Hello"). Esto se parece notablemente a llamar a un método en un objeto en otros lenguajes. La estructura contiene tanto sus datos como la función que opera sobre ellos.

Este patrón es la base del polimorfismo en C: distintas instancias pueden tener diferentes funciones asignadas, lo que produce comportamientos diferentes a partir del mismo tipo de estructura.

challenge icon

Desafío

Fácil

Construyamos un sistema Notifier que demuestre cómo las estructuras pueden llevar su propio comportamiento mediante punteros a funciones.

Crearás dos archivos para organizar tu código:

  • notifier.h: Define un tipo de puntero a función llamado NotifyFunc que recibe un parámetro const char* y no devuelve nada. Después, define una estructura Notifier que contenga un name (un const char*) y un puntero a función notify de tipo NotifyFunc.
  • main.c: Incluye tu archivo de encabezado e implementa dos funciones de notificación:
    • alert_notify: imprime el mensaje con el formato: [ALERT] message
    • info_notify: imprime el mensaje con el formato: [INFO] message
    Después, crea una instancia de Notifier, asígnale la función adecuada según la entrada y llama a la notificación mediante el puntero a función de la estructura.

Tu programa recibirá dos entradas: un tipo de notificación (1 para alerta, 2 para información) y un mensaje que mostrar.

Según el tipo, asigna la función correspondiente al miembro notify de tu notificador y después llámala a través de la estructura para mostrar el mensaje.

Salida de ejemplo cuando el tipo es 1 y el mensaje es "System starting":

[ALERT] System starting

Salida de ejemplo cuando el tipo es 2 y el mensaje es "All systems normal":

[INFO] All systems normal

Recuerda usar protectores de inclusión en tu archivo de encabezado y llamar a la función mediante el miembro de la estructura: n.notify(message)

Pruébalo tú mismo

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

// TODO: Implementa la función alert_notify
// Debe imprimir: [ALERT] message


// TODO: Implementa la función info_notify
// Debe imprimir: [INFO] message


int main() {
    int type;
    char message[256];
    
    // Leer la entrada
    scanf("%d", &type);
    getchar(); // consumir el salto de línea
    fgets(message, sizeof(message), stdin);
    
    // Eliminar el salto de línea final del mensaje si está presente
    int len = 0;
    while (message[len] != '\0') len++;
    if (len > 0 && message[len-1] == '\n') message[len-1] = '\0';
    
    // TODO: Crea una instancia de Notifier
    
    
    // TODO: Basado en type (1 para alert, 2 para info),
    // asigna la función apropiada al miembro notify del notifier
    
    
    // TODO: Llama a la notificación a través del puntero a función de la struct
    // Usa: n.notify(message)
    
    
    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