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.
Desafio
FácilVamos 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 esse sistema polimórfico:
shape.h: Defina aqui a interface principal. Primeiro, crie uma declaração antecipada para a structShape. Em seguida, defina dois tipos de ponteiros para funções:DrawFunc: recebe um parâmetroconst Shape*e não retorna nadaAreaFunc: recebe um parâmetroconst Shape*e retorna umdouble
Shape, contendo dois ponteiros para funções:draw(do tipoDrawFunc) earea(do tipoAreaFunc). Essa struct funciona puramente como uma interface. Ela não contém dados específicos de nenhuma forma, apenas comportamento.main.c: Demonstre que sua interface funciona criando uma forma simples de teste. Implemente duas funções:test_draw: imprimeDrawing test shapetest_area: retorna42.0
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.0Por que a declaração antecipada? Você pode se perguntar por que typedef struct Shape Shape; aparece antes de a struct estar totalmente definida. Isso é necessário porque DrawFunc e AreaFunc fazem referência a const Shape* nos tipos de seus parâmetros, 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 depois. 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 ideia principal aqui é que Shape não sabe nada sobre círculos ou retângulos. Ela sabe apenas que qualquer forma deve ser capaz de se 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 arquivo de cabeçalho.
Experimente você mesmo
#include <stdio.h>
#include "shape.h"
// TODO: Implemente a função test_draw
// - Recebe um parâmetro const Shape*
// - Imprime "Drawing test shape"
void test_draw(const Shape* shape) {
// TODO: Imprima a mensagem necessária
}
// TODO: Implemente a função test_area
// - Recebe um parâmetro const Shape*
// - Retorna 42.0
double test_area(const Shape* shape) {
// TODO: Retorne o valor da área de teste
}
int main() {
// TODO: Crie uma instância de Shape
// TODO: Associe a forma às funções test_draw e test_area
// TODO: Chame draw por meio da interface
// TODO: Chame area por meio da interface e imprima com uma casa decimal
// Formato: "Area: %.1f\n"
return 0;
}
Todas as lições de Programação Orientada a Objetos
1Fundamentos da Programação Modular
Arquivos de cabeçalhoProteções de inclusãoArquivos-fonteFunções estáticasRevisão: calculadora modular4Encapsulamento
Conceito de ponteiros opacosDefinindo structs opacasGetters e settersValidação em settersRevisão: caixa secreta2Objetos e métodos
Structs como objetosO ponteiro 'Self'Correção de constPonteiro vs. valorMétodos auxiliaresRevisão: Gerenciador de pontos5Projeto: Conta Bancária Simples
Configuração do ProjetoImplementação da Conta3Ciclo de vida do objeto
Padrão de construtorPadrão de destrutorInicialização da pilhaCópia profundaRevisão: wrapper de String6Herança por composição
Incorporação de structRegra do primeiro membroAcessando membros do tipo paiUpcastingRevisão: hierarquia de formas9Projeto: Desenhador de Formas
Visão geral do projetoImplementação do círculoImplementação do retânguloUso polimórficoContêiner de formasPratique por conta própria: Compilador de C online