Menu
Coddy logo textTech

Simulare i metodi

Fa parte della sezione Programmazione orientata agli oggetti del percorso C di Coddy. Lezione 39 di 61.

Hai visto come inserire un puntatore a funzione in una struct. Il vero potere emerge quando assegni funzioni diverse a istanze diverse dello stesso tipo di struct. È così che simuliamo metodi con comportamenti diversi.

Considera una struct che rappresenta un'azione con una logica personalizzabile:

typedef void (*ActionFunc)(void);

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

Quando crei le istanze, colleghi funzioni diverse a ciascuna di esse:

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();    // Output: Hello!
    farewell.execute(); // Output: Goodbye!
    return 0;
}

Sia greet che farewell sono dello stesso tipo (Action), eppure chiamare execute su ciascuno produce risultati completamente diversi. La struct non contiene solo dati: contiene un comportamento che varia a seconda dell'istanza.

Questo schema rispecchia il funzionamento degli oggetti in altri linguaggi: ogni oggetto può avere una propria implementazione di un metodo, anche se condividono la stessa interfaccia.

challenge icon

Sfida

Facile

Costruiamo un sistema Speaker che dimostri come istanze diverse dello stesso tipo di struct possano manifestare comportamenti completamente diversi a seconda della funzione collegata a ciascuna di esse.

Creerai due file per organizzare il tuo codice:

  • speaker.h: Definisci un tipo puntatore a funzione chiamato SpeakFunc che non accetta parametri e non restituisce nulla. Poi definisci una struct Speaker contenente un name (un const char*) e un puntatore a funzione speak di tipo SpeakFunc.
  • main.c: Includi il tuo header e implementa tre diverse funzioni per parlare:
    • bark: stampa Woof!
    • meow: stampa Meow!
    • chirp: stampa Chirp!
    Poi crea due istanze di Speaker, ciascuna collegata a una funzione diversa in base all'input, e chiama i loro metodi speak per vedere il polimorfismo in azione.

Il tuo programma riceverà due input: il tipo del primo interlocutore (1 per bark, 2 per meow, 3 per chirp) e il tipo del secondo interlocutore (anch'esso 1, 2 o 3).

Crea due istanze di Speaker. Puoi chiamarle come preferisci (ad esempio "Dog", "Cat", "Bird" o semplicemente "Speaker1", "Speaker2"). Collega ciascuna alla funzione appropriata in base al suo codice di input, poi chiama speak su ogni istanza nell'ordine.

Esempio di output quando il primo tipo è 1 e il secondo tipo è 2:

Woof!
Meow!

Esempio di output quando il primo tipo è 3 e il secondo tipo è 3:

Chirp!
Chirp!

L'intuizione chiave è che entrambi gli interlocutori sono dello stesso tipo Speaker, eppure producono output diversi perché a ciascuno è assegnata una funzione diversa nel membro speak. Ricorda di usare le guardie di inclusione nel tuo file header.

Provalo tu

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

// TODO: Implementa la funzione bark che stampa "Woof!"

// TODO: Implementa la funzione meow che stampa "Meow!"

// TODO: Implementa la funzione chirp che stampa "Chirp!"

int main() {
    int type1, type2;
    scanf("%d", &type1);
    scanf("%d", &type2);
    
    // TODO: Crea due istanze di Speaker
    
    // TODO: Collega la funzione speak del primo speaker in base a type1
    // (1 = bark, 2 = meow, 3 = chirp)
    
    // TODO: Collega la funzione speak del secondo speaker in base a type2
    // (1 = bark, 2 = meow, 3 = chirp)
    
    // TODO: Chiama speak su ciascuno speaker nell'ordine previsto
    
    return 0;
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore C online