Contenedor de figuras
Parte de la sección Object Oriented Programming del Journey de C de Coddy — lección 48 de 61.
Desafío
Fácil¡Llevemos el proyecto Shape Drawer a su gran final! Crearás un contenedor de formas que albergue una colección mixta de círculos (Circles) y rectángulos (Rectangles), luego iterarás a través de ellos para calcular el área total, demostrando el verdadero poder del polimorfismo.
Basándote en todo lo que has creado hasta ahora, tu proyecto completo incluirá:
shape.hyshape.c: Tu interfaz base Shape y la funciónprocess_shape.circle.hycircle.c: Tu implementación de Circle con su constructor y cálculo de área.rectangle.hyrectangle.c: Tu implementación de Rectangle con su constructor y cálculo de área.main.c: Aquí es donde ocurre la magia. Crearás un arreglo de punterosShape*que puede contener cualquier tipo de forma. Llénalo con una mezcla de Circles y Rectangles, luego recorre el arreglo para calcular y mostrar el área total de todas las formas combinadas.
Tu programa recibirá las siguientes entradas:
- El número de formas a crear
- Para cada forma: un indicador de tipo (
cpara círculo,rpara rectángulo) seguido de sus dimensiones
Para cada forma en tu contenedor, imprime su salida de dibujo (draw). Después de procesar todas las formas, imprime el área total con 2 decimales en el formato Total Area: X.XX.
Ejemplo con las entradas 3, luego c 5.0, r 4.0 3.0, c 2.0:
Drawing Circle with radius: 5.00
Drawing Rectangle with width: 4.00 and height: 3.00
Drawing Circle with radius: 2.00
Total Area: 103.11Ejemplo con las entradas 2, luego r 6.0 4.0, r 3.0 2.0:
Drawing Rectangle with width: 6.00 and height: 4.00
Drawing Rectangle with width: 3.00 and height: 2.00
Total Area: 30.00La idea clave es que tu arreglo almacena punteros Shape*; no le importa si cada elemento es en realidad un Circle o un Rectangle. Cuando iteras y llamas a draw y area a través de cada puntero, la implementación correcta se ejecuta automáticamente según cómo se construyó cada forma. Esto es el polimorfismo en acción: un bucle, una interfaz, múltiples comportamientos.
Recuerda que necesitarás almacenar punteros a los miembros Shape embebidos de tus formas concretas en el arreglo. Usa 3.14159 para π en los cálculos del área del círculo.
Importante — lectura del carácter de tipo de forma: Después de leer el número de formas con scanf("%d", &n), cada llamada posterior para leer el carácter de tipo debe omitir el salto de línea sobrante en el búfer de entrada. Usa un espacio inicial en la cadena de formato para hacer esto:
scanf(" %c", &type); // nota el espacio antes de %cSin el espacio inicial, scanf leerá el carácter de salto de línea que quedó de la entrada anterior en lugar de la c o r deseada, lo que provocará que tu comprobación del tipo de forma falle silenciosamente y no produzca ninguna salida.
Pruébalo tú mismo
#include <stdio.h>
#include <stdlib.h>
#include "shape.h"
#include "circle.h"
#include "rectangle.h"
int main() {
// TODO: Leer el número de formas
// TODO: Asignar arreglos para círculos, rectángulos y punteros Shape*
// TODO: Recorrer cada forma, leer su tipo y dimensiones,
// crear la forma y almacenar un puntero a su base en el arreglo shapes
// TODO: Recorrer el arreglo shapes, llamar a draw en cada forma,
// y acumular el área total
// TODO: Imprimir el área total en el formato: Total Area: X.XX
// TODO: Liberar la memoria asignada
return 0;
}
Todas las lecciones de Object Oriented Programming
1Fundamentos de programación modular
Archivos de cabeceraGuardas de inclusiónArchivos fuenteFunciones estáticasRepaso: Calculadora modular4Encapsulamiento
Concepto de punteros opacosDefinición de structs opacosGetters y SettersValidación en settersResumen: Caja secreta7Punteros a funciones
Declaración de punteros a funcionesLlamada a punteros a funcionesTypedef para punteros a funcionesPasar funciones como argumentosRepaso: Dispatch de calculadora10Contenedores genéricos
Repaso de punteros voidWrapper genéricoSwap genéricoComparación genéricaRepaso: Array genérico2Objetos y métodos
Structs como objetosEl puntero 'Self'Const CorrectnessPuntero vs. ValorMétodos auxiliaresResumen: Point Manager5Proyecto: Cuenta bancaria simple
Configuración del proyectoImplementación de la cuenta3Ciclo de vida de los objetos
Patrón ConstructorPatrón DestructorInicialización en StackCopia profundaResumen: String Wrapper6Herencia mediante composición
Incrustación de StructsLa regla del primer miembroAcceso a miembros padreUpcastingResumen: Jerarquía de formas9Proyecto: Dibujador de figuras
Descripción general del proyectoImplementación del círculo