Menu
Coddy logo textTech

Visão Geral do Projeto

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

challenge icon

Desafio

Fácil

Vamos estabelecer a base do projeto Shape Drawer criando a struct base Shape: uma interface que define o que qualquer forma pode fazer por meio de ponteiros para funções.

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

  • shape.h: defina a interface principal aqui. Primeiro, crie uma declaração antecipada para a struct Shape. Em seguida, defina dois tipos de ponteiro para funções:
    • DrawFunc: recebe um parâmetro const Shape* e não retorna nada
    • AreaFunc: recebe um parâmetro const Shape* e retorna um double
    Por fim, defina a própria struct Shape, contendo dois ponteiros para funções: draw (do tipo DrawFunc) e area (do tipo AreaFunc). Essa struct funciona puramente como uma interface. Ela não contém dados específicos de formas, 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, associe-a a essas funções de teste e, em seguida, chame ambas por meio da interface. Imprima o resultado da área com uma casa decimal.

Sua saída deve demonstrar que os ponteiros para funções 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 de a struct ser completamente definida. Isso é necessário porque DrawFunc e AreaFunc fazem referência a const Shape* em seus tipos de parâmetro, mas, nesse ponto do arquivo, o compilador ainda não viu a definição completa da struct. A declaração antecipada informa ao compilador: "existe uma struct chamada Shape", o que é suficiente para usar um ponteiro para ela. A definição completa vem mais adiante. Esse padrão é comum em C sempre que uma struct precisa fazer referência a si mesma (diretamente ou por meio de ponteiros para funções).

A principal ideia aqui é que Shape não sabe nada sobre círculos ou retângulos. Ela só sabe que qualquer forma deve ser capaz de executar draw e calcular sua area. Nas próximas lições, você criará formas concretas que incorporam essa struct base e fornecem suas próprias implementações. Lembre-se de usar guardas de inclusão no 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*
// - Prints "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 da área de teste
}

int main() {
    // TODO: Criar uma instância de Shape
    
    // TODO: Conectar o shape à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 Programação Orientada a Objetos

Pratique por conta própria: Compilador de C online