Menu
CoddyTech

Simulando métodos

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

Ya has visto cómo colocar un puntero a función dentro de una estructura. El verdadero potencial aparece cuando asignas funciones diferentes a distintas instancias del mismo tipo de estructura. Así simulamos métodos con comportamientos variados.

Considera una estructura que representa una acción con lógica personalizable:

typedef void (*ActionFunc)(void);

typedef struct {
    const char* name;
    ActionFunc execute;
} Action;

Al crear instancias, conectas funciones diferentes a cada una:

void say_hello(void) {
    printf("Hello!\n");
}

void say_goodbye(void) {
    printf("Goodbye!\n");
}

int main() {
    Action greet = { "Greet", say_hello };
    Action farewell = { "Farewell", say_goodbye };
    
    greet.execute();    // Salida: Hello!
    farewell.execute(); // Salida: Goodbye!
    return 0;
}

Tanto greet como farewell son del mismo tipo (Action), pero llamar a execute en cada uno produce resultados completamente diferentes. La estructura no solo contiene datos. Contiene un comportamiento que varía según la instancia.

Este patrón refleja cómo funcionan los objetos en otros lenguajes: cada objeto puede tener su propia implementación de un método, aunque compartan la misma interfaz.

challenge icon

Desafío

Fácil

Vamos a crear un sistema Speaker que demuestra cómo distintas instancias del mismo tipo de estructura pueden tener comportamientos completamente diferentes según la función que se les asigne.

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

  • speaker.h: Define un tipo de puntero a función llamado SpeakFunc que no recibe parámetros y no devuelve nada. Luego define una estructura Speaker que contenga un name (un const char*) y un puntero a función speak de tipo SpeakFunc.
  • main.c: Incluye tu archivo de encabezado e implementa tres funciones diferentes para hablar:
    • bark: imprime Woof!
    • meow: imprime Meow!
    • chirp: imprime Chirp!
    Luego crea dos instancias de Speaker, asigna a cada una una función diferente según la entrada y llama a sus métodos speak para ver el polimorfismo en acción.

Tu programa recibirá dos entradas: el tipo del primer hablante (1 para ladrar, 2 para maullar, 3 para gorjear) y el tipo del segundo hablante (también 1, 2 o 3).

Crea dos instancias de Speaker. Puedes llamarlas como quieras (por ejemplo, "Dog", "Cat", "Bird" o simplemente "Speaker1", "Speaker2"). Asigna a cada una la función adecuada según su código de entrada y luego llama a speak en cada instancia, en orden.

Salida de ejemplo cuando el primer tipo es 1 y el segundo tipo es 2:

Woof!
Meow!

Salida de ejemplo cuando el primer tipo es 3 y el segundo tipo es 3:

Chirp!
Chirp!

La idea clave es que ambos hablantes son del mismo tipo Speaker, pero producen salidas diferentes porque cada uno tiene asignada una función distinta en su miembro speak. Recuerda usar guardas de inclusión en el archivo de encabezado.

Pruébalo tú mismo

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

// TODO: Implementa la función bark que imprime "Woof!"

// TODO: Implementa la función meow que imprime "Meow!"

// TODO: Implementa la función chirp que imprime "Chirp!"

int main() {
    int type1, type2;
    scanf("%d", &type1);
    scanf("%d", &type2);
    
    // TODO: Crea dos instancias de Speaker
    
    // TODO: Asigna la función speak del primer Speaker según type1
    // (1 = bark, 2 = meow, 3 = chirp)
    
    // TODO: Asigna la función speak del segundo Speaker según type2
    // (1 = bark, 2 = meow, 3 = chirp)
    
    // TODO: Llama a speak en cada Speaker en orden
    
    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