Menu
Coddy logo textTech

Ponteiros de Função em Structs

Parte da seção Programação Orientada a Objetos do Journey de C da Coddy. Lição 38 de 61.

Até agora, usamos ponteiros para funções como variáveis independentes ou os passamos como argumentos. O próximo passo em direção ao polimorfismo é incorporar um ponteiro para função diretamente em uma struct, dando à struct seu próprio comportamento.

Quando uma struct contém um ponteiro para função, cada instância pode armazenar uma função diferente. Isso significa que dois objetos do mesmo tipo podem se comportar de maneira diferente quando você chama seu ponteiro para função:

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

typedef struct {
    const char* name;
    PrintFunc print;  // Ponteiro de função como um membro
} Printer;

A estrutura Printer agora tem dois membros: dados (name) e comportamento (print). Para usá-la, você atribui uma função ao ponteiro durante a inicialização:

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

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

Observe como chamamos a função por meio da struct: p.print("Hello"). Isso se parece bastante com chamar um método em um objeto em outras linguagens. A struct contém tanto seus dados quanto a função que opera sobre eles.

Esse padrão é a base do polimorfismo em C: diferentes instâncias podem ter funções diferentes atribuídas, produzindo comportamentos diferentes a partir do mesmo tipo de struct.

challenge icon

Desafio

Fácil

Vamos criar um sistema Notifier que demonstra como as structs podem carregar seu próprio comportamento por meio de ponteiros para funções.

Você criará dois arquivos para organizar seu código:

  • notifier.h: Defina um tipo de ponteiro para função chamado NotifyFunc que recebe um parâmetro const char* e não retorna nada. Em seguida, defina uma struct Notifier que contém um name (um const char*) e um ponteiro para a função notify do tipo NotifyFunc.
  • main.c: Inclua seu header e implemente duas funções de notificação:
    • alert_notify: imprime a mensagem no formato: [ALERT] message
    • info_notify: imprime a mensagem no formato: [INFO] message
    Em seguida, crie uma instância de Notifier, associe a função apropriada com base na entrada e chame a notificação por meio do ponteiro para função da struct.

Seu programa receberá duas entradas: um tipo de notificação (1 para alerta, 2 para informação) e uma mensagem a ser exibida.

Com base no tipo, atribua a função correspondente ao membro notify do seu notifier e, em seguida, chame-a por meio da struct para exibir a mensagem.

Exemplo de saída quando o tipo é 1 e a mensagem é "System starting":

[ALERT] System starting

Exemplo de saída quando o tipo é 2 e a mensagem é "All systems normal":

[INFO] All systems normal

Lembre-se de usar include guards no seu arquivo de header e de chamar a função por meio do membro da struct: n.notify(message)

Experimente você mesmo

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

// TODO: Implemente a função alert_notify
// Deve imprimir: [ALERT] message


// TODO: Implemente a função info_notify
// Deve imprimir: [INFO] message


int main() {
    int type;
    char message[256];
    
    // Lê a entrada
    scanf("%d", &type);
    getchar(); // consome a nova linha
    fgets(message, sizeof(message), stdin);
    
    // Remove a nova linha final da mensagem se presente
    int len = 0;
    while (message[len] != '\0') len++;
    if (len > 0 && message[len-1] == '\n') message[len-1] = '\0';
    
    // TODO: Crie uma instância de Notifier
    
    
    // TODO: Com base no type (1 para alert, 2 para info),
    // atribua a função apropriada ao membro notify do notifier
    
    
    // TODO: Chame a notificação através do ponteiro de função da struct
    // Use: n.notify(message)
    
    
    return 0;
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Compilador de C online