Menu
Coddy logo textTech

Wrapper Genérico

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

Um void* sozinho pode armazenar qualquer dado, mas tem uma falha crítica: você perde o controle de qual tipo ele contém. Para criar contêineres genéricos realmente úteis, precisamos associar o ponteiro de dados às informações de tipo. É aí que entra o padrão Generic Wrapper.

A ideia é simples: crie uma struct que agrupe um void* com um enum que identifique o tipo armazenado. Dessa forma, o wrapper sempre sabe como interpretar seu conteúdo.

typedef enum {
    TYPE_INT,
    TYPE_STRING
} DataType;

typedef struct {
    void* data;
    DataType type;
} Wrapper;

Ao armazenar dados, você aloca memória para o valor real e registra seu tipo. Ao recuperá-los, verifica o tipo antes de fazer a conversão:

Wrapper wrap_int(int value) {
    int* p = malloc(sizeof(int));
    *p = value;
    return (Wrapper){ .data = p, .type = TYPE_INT };
}

void print_wrapper(Wrapper* w) {
    if (w->type == TYPE_INT) {
        printf("%d\n", *(int*)w->data);
    } else if (w->type == TYPE_STRING) {
        printf("%s\n", (char*)w->data);
    }
}

Esse padrão é a base para criar contêineres genéricos com segurança de tipos em C. O enum atua como uma tag de tipo em tempo de execução, permitindo que seu código tome decisões seguras sobre como lidar com os dados armazenados.

challenge icon

Desafio

Fácil

Vamos criar um sistema genérico de wrappers com segurança de tipos que possa armazenar um inteiro ou uma string, mantendo o controle do tipo que ele contém para que possamos recuperar e imprimir os dados com segurança posteriormente.

Você organizará seu código em três arquivos:

  • wrapper.h: Defina um enum DataType com os valores TYPE_INT e TYPE_STRING. Em seguida, defina uma struct Wrapper que reúna um ponteiro de dados void* com um campo DataType. Declare os protótipos das funções para criar wrappers e imprimir seu conteúdo.
  • wrapper.c: Implemente a funcionalidade do wrapper:
    • wrap_int: recebe um inteiro, aloca memória para ele, armazena o valor e retorna um Wrapper com a tag de tipo apropriada
    • wrap_string: recebe uma string (char*), aloca memória e copia a string, e retorna um Wrapper com a tag de tipo de string
    • print_wrapper: verifica a tag de tipo e imprime os dados adequadamente (inteiro como está, string como está)
    • free_wrapper: libera os dados alocados dinamicamente dentro do wrapper
  • main.c: Reúna tudo. Leia um indicador de tipo (i para inteiro, s para string) seguido pelo valor. Crie o wrapper apropriado, imprima seu conteúdo e libere a memória.

Seu programa receberá duas entradas:

  1. Um indicador de tipo: i para inteiro ou s para string
  2. O valor a ser encapsulado

Exemplo de saída quando as entradas são i e 42:

42

Exemplo de saída quando as entradas são s e Hello:

Hello

Exemplo de saída quando as entradas são i e -100:

-100

Exemplo de saída quando as entradas são s e Generic Programming:

Generic Programming

Lembre-se de usar guardas de inclusão no seu arquivo de cabeçalho. Para copiar strings, aloque espaço suficiente para a string mais o terminador nulo usando strlen e strcpy.

Experimente você mesmo

#include <stdio.h>
#include <string.h>
#include "wrapper.h"

int main() {
    char type;
    scanf("%c", &type);
    getchar(); // consumir nova linha
    
    Wrapper w;
    
    if (type == 'i') {
        int value;
        scanf("%d", &value);
        // TODO: Crie um wrapper de inteiro usando wrap_int
        
    } else if (type == 's') {
        char str[256];
        fgets(str, sizeof(str), stdin);
        // Remova a nova linha final se presente
        str[strcspn(str, "\n")] = '\0';
        // TODO: Crie um wrapper de string usando wrap_string
        
    }
    
    // TODO: Imprima o conteúdo do wrapper usando print_wrapper
    
    // TODO: Libere a memória do wrapper usando free_wrapper
    
    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