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 este sistema polimórfico:
shape.h: defina a interface principal aqui. Primeiro, crie uma declaração antecipada para a structShape. Em seguida, defina dois tipos de ponteiro 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 formas, apenas comportamento.main.c: demonstre que sua interface funciona criando uma forma de teste simples. 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 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
1Fundamentos da Programação Modular
Arquivos de CabeçalhoInclude GuardsArquivos-FonteFunções EstáticasRecapitulação: Calculadora Modular4Encapsulamento
Conceito de Ponteiros OpacosDefinindo Structs OpacasGetters e SettersValidação em SettersRecapitulação: Caixa Secreta2Objetos e Métodos
Structs como ObjetosO Ponteiro 'Self'Const CorrectnessPonteiro vs ValorMétodos AuxiliaresRecapitulação: Point Manager5Projeto: Conta Bancária Simples
Configuração do ProjetoImplementação da Conta3Ciclo de Vida de Objetos
Padrão de ConstrutorPadrão de DestrutorInicialização na StackCópia ProfundaRecapitulação: String Wrapper6Herança via Composição
Incorporação de StructsA Regra do Primeiro MembroAcessando Membros PaiUpcastingRecapitulação: Hierarquia de Formas9Projeto: Desenhador de Formas
Visão Geral do ProjetoImplementação do CírculoImplementação do RetânguloUso PolimórficoContainer de FormasPratique por conta própria: Compilador de C online