Menu
Coddy logo textTech

Visão Geral do Projeto

Parte da seção Object Oriented Programming do Journey de C da Coddy — lição 44 de 61.

challenge icon

Desafio

Fácil

Vamos lançar as bases para o projeto Shape Drawer criando a struct base Shape — uma interface que define o que qualquer forma pode fazer através de ponteiros de função.

Você criará dois arquivos para configurar este sistema polimórfico:

  • shape.h: Defina a interface principal aqui. Primeiro, crie uma declaração antecipada (forward declaration) para a struct Shape. Em seguida, defina dois tipos de ponteiros de função:
    • DrawFunc — recebe um parâmetro const Shape* e não retorna nada
    • AreaFunc — recebe um parâmetro const Shape* e retorna um double
    Finalmente, defina a própria struct Shape contendo dois ponteiros de função: draw (do tipo DrawFunc) e area (do tipo AreaFunc). Esta struct atua puramente como uma interface — ela não contém dados específicos da forma, apenas comportamento.
  • main.c: Demonstre que sua interface funciona criando uma forma de teste simples. Implemente duas funções:
    • test_draw — imprime Drawing test shape
    • test_area — retorna 42.0
    Crie uma instância de Shape, conecte-a a essas funções de teste e, em seguida, chame ambas através da interface. Imprima o resultado da área com uma casa decimal.

Sua saída deve demonstrar que os ponteiros de função funcionam corretamente:

Drawing test shape
Area: 42.0

Por que a declaração antecipada? Você pode se perguntar por que typedef struct Shape Shape; aparece antes da struct ser totalmente definida. Isso é necessário porque DrawFunc e AreaFunc referenciam const Shape* em seus tipos de parâmetros — mas, nesse ponto do arquivo, o compilador ainda não viu a definição completa da struct. A declaração antecipada diz ao compilador: "uma struct chamada Shape existe", o que é suficiente para usar um ponteiro para ela. A definição completa segue depois. Esse padrão é comum em C sempre que uma struct precisa referenciar a si mesma (diretamente ou através de ponteiros de função).

A ideia central aqui é que Shape não sabe nada sobre círculos ou retângulos — ela apenas sabe que qualquer forma deve ser capaz de desenhar (draw) a si mesma e calcular sua área (area). Nas próximas lições, você criará formas concretas que incorporam esta struct base e fornecem suas próprias implementações. Lembre-se de usar guards de inclusão (include guards) em seu arquivo de cabeçalho.

Experimente você mesmo

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

// TODO: Implementar a função test_draw
// - Recebe um parâmetro const Shape*
// - Imprime "Drawing test shape"
void test_draw(const Shape* shape) {
    // TODO: Imprimir a mensagem solicitada
}

// TODO: Implementar a função test_area
// - Recebe um parâmetro const Shape*
// - Retorna 42.0
double test_area(const Shape* shape) {
    // TODO: Retornar o valor de área de teste
}

int main() {
    // TODO: Criar uma instância de Shape
    
    // TODO: Vincular a forma às funções test_draw e test_area
    
    // TODO: Chamar draw através da interface
    
    // TODO: Chamar area através da interface e imprimir com uma casa decimal
    // Formato: "Area: %.1f\n"
    
    return 0;
}

Todas as lições de Object Oriented Programming