Menu
Coddy logo textTech

Puntatori a funzione nelle struct

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

Finora abbiamo usato puntatori a funzione come variabili autonome o li abbiamo passati come argomenti. Il passo successivo verso il polimorfismo consiste nell’inserire un puntatore a funzione direttamente all’interno di una struct, dando alla struct un comportamento proprio.

Quando una struct contiene un puntatore a funzione, ogni istanza può contenere una funzione diversa. Questo significa che due oggetti dello stesso tipo possono comportarsi in modo diverso quando chiami il loro puntatore a funzione:

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

typedef struct {
    const char* name;
    PrintFunc print;  // Puntatore a funzione come membro
} Printer;

La struct Printer ora ha due membri: dati (name) e comportamento (print). Per usarla, assegni una funzione al puntatore durante l'inizializzazione:

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

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

Nota come chiamiamo la funzione tramite la struct: p.print("Hello"). Questo assomiglia molto alla chiamata di un metodo su un oggetto in altri linguaggi. La struct contiene sia i propri dati sia la funzione che opera su di essa.

Questo schema è alla base del polimorfismo in C: a istanze diverse possono essere assegnate funzioni diverse, producendo comportamenti diversi a partire dallo stesso tipo di struct.

challenge icon

Sfida

Facile

Costruiamo un sistema Notifier che dimostra come le struct possano contenere il proprio comportamento tramite puntatori a funzione.

Creerai due file per organizzare il codice:

  • notifier.h: definisci un tipo puntatore a funzione chiamato NotifyFunc che accetta un parametro const char* e non restituisce nulla. Poi definisci una struct Notifier che contiene un name (un const char*) e un puntatore a funzione notify di tipo NotifyFunc.
  • main.c: includi il tuo header e implementa due funzioni di notifica:
    • alert_notify: stampa il messaggio nel formato: [ALERT] message
    • info_notify: stampa il messaggio nel formato: [INFO] message
    Poi crea un'istanza di Notifier, assegna la funzione appropriata in base all'input e richiama la notifica tramite il puntatore a funzione della struct.

Il programma riceverà due input: un tipo di notifica (1 per alert, 2 per info) e un messaggio da visualizzare.

In base al tipo, assegna la funzione corrispondente al membro notify del notifier, quindi richiamala tramite la struct per visualizzare il messaggio.

Esempio di output quando il tipo è 1 e il messaggio è "System starting":

[ALERT] System starting

Esempio di output quando il tipo è 2 e il messaggio è "All systems normal":

[INFO] All systems normal

Ricorda di usare include guard nel file header e di richiamare la funzione tramite il membro della struct: n.notify(message)

Provalo tu

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

// TODO: Implementa la funzione alert_notify
// Deve stampare: [ALERT] message


// TODO: Implementa la funzione info_notify
// Deve stampare: [INFO] message


int main() {
    int type;
    char message[256];
    
    // Leggi l'input
    scanf("%d", &type);
    getchar(); // consuma il carattere di nuova riga
    fgets(message, sizeof(message), stdin);
    
    // Rimuovi il carattere di nuova riga finale da message, se presente
    int len = 0;
    while (message[len] != '\0') len++;
    if (len > 0 && message[len-1] == '\n') message[len-1] = '\0';
    
    // TODO: Crea un'istanza di Notifier
    
    
    // TODO: In base a type (1 per alert, 2 per info),
    // assegna la funzione appropriata al membro notify di notifier
    
    
    // TODO: Richiama la notifica tramite il puntatore a funzione della struct
    // Usa: n.notify(message)
    
    
    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