Contenedor de figuras
Parte de la sección Programación Orientada a Objetos 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 almacene una colección mixta de círculos y rectángulos, y después iterarás sobre 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 el cálculo del área.rectangle.hyrectangle.c: tu implementación de Rectangle con su constructor y el cálculo del área.main.c: aquí es donde ocurre la magia. Crearás un arreglo de punterosShape*que pueda almacenar cualquier tipo de forma. Lo llenarás con una combinación de círculos y rectángulos, y después recorrerás el arreglo para calcular y mostrar el área total de todas las formas combinadas.
Tu programa recibirá las siguientes entradas:
- La cantidad de formas que se crearán
- Para cada forma: un indicador de tipo (
cpara círculo,rpara rectángulo) seguido de sus dimensiones
Para cada forma de tu contenedor, llama tú mismo a draw y area a través del puntero Shape* (shapes[i]->draw(shapes[i]), shapes[i]->area(shapes[i])) y añade el área a un total acumulado. No uses process_shape de shape.c aquí: imprime una línea adicional Area: para cada forma, que no aparece en la salida esperada. 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, después 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, después 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 realmente 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 haya construido cada forma. Esto es el polimorfismo en acción: un bucle, una interfaz y múltiples comportamientos.
Recuerda que tendrás que almacenar en el arreglo punteros a los miembros Shape integrados en tus formas concretas. Usa 3.14159 para π en los cálculos del área de los círculos.
Importante: leer el carácter del tipo de forma: Después de leer la cantidad de formas con scanf("%d", &n), cada llamada posterior para leer el carácter del 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 hacerlo:
scanf(" %c", &type); // note the space before %cSin el espacio inicial, scanf leerá el carácter de salto de línea que quedó de la entrada anterior en lugar del c o r esperado, lo que hará que la 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 arrays para circles, rectangles y punteros Shape*
// TODO: Recorrer cada forma, leer su tipo y dimensiones,
// crear la forma, y almacenar un puntero a su base en el array shapes
// TODO: Recorrer el array shapes, llamar a shapes[i]->draw(...) y
// shapes[i]->area(...) directamente y acumular el área total
// (no llamar a process_shape: imprime una línea Area extra)
// TODO: Imprimir el área total en el formato: Total Area: X.XX
// TODO: Liberar la memoria asignada
return 0;
}
Todas las lecciones de Programación Orientada a Objetos
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írculoImplementación del rectánguloUso polimórficoContenedor de figurasPractica por tu cuenta: Compilador de C online