Menu
Coddy logo textTech

Contenitore di forme

Fa parte della sezione Programmazione orientata agli oggetti del percorso C di Coddy. Lezione 48 di 61.

challenge icon

Sfida

Facile

Portiamo il progetto Shape Drawer al gran finale! Creerai un contenitore di forme che ospita una raccolta mista di Circle e Rectangle, poi li scorrerai per calcolare l’area totale: dimostrando la vera potenza del polimorfismo.

Partendo da tutto ciò che hai creato finora, il progetto completo includerà:

  • shape.h e shape.c: la tua interfaccia Shape di base e la funzione process_shape.
  • circle.h e circle.c: l’implementazione di Circle, con il relativo costruttore e il calcolo dell’area.
  • rectangle.h e rectangle.c: l’implementazione di Rectangle, con il relativo costruttore e il calcolo dell’area.
  • main.c: qui avviene la magia. Creerai un array di puntatori Shape* in grado di contenere qualsiasi tipo di forma. Riempilo con un insieme misto di Circle e Rectangle, poi scorri l’array per calcolare e visualizzare l’area totale di tutte le forme.

Il programma riceverà i seguenti input:

  1. Il numero di forme da creare
  2. Per ogni forma: un indicatore di tipo (c per Circle, r per Rectangle) seguito dalle sue dimensioni

Per ogni forma nel contenitore, chiama tu stesso draw e area tramite il puntatore Shape* (shapes[i]->draw(shapes[i]), shapes[i]->area(shapes[i])) e aggiungi l’area a un totale progressivo. Non usare qui process_shape di shape.c: stampa una riga Area: aggiuntiva per ogni forma, che non è prevista nell’output atteso. Dopo aver elaborato tutte le forme, stampa l’area totale con 2 cifre decimali nel formato Total Area: X.XX.

Esempio con gli input 3, poi 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.11

Esempio con gli input 2, poi 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.00

L’idea fondamentale è che il tuo array memorizza puntatori Shape*. Non importa se ciascun elemento è effettivamente un Circle o un Rectangle. Quando scorri l’array e chiami draw e area tramite ciascun puntatore, viene eseguita automaticamente l’implementazione corretta, in base a come è stata creata ogni forma. Questo è il polimorfismo in azione: un ciclo, un’interfaccia, comportamenti multipli.

Ricorda che dovrai memorizzare nell’array i puntatori ai membri Shape incorporati nelle forme concrete. Usa 3.14159 per π nei calcoli dell’area dei cerchi.

Importante: leggere il carattere che indica il tipo di forma: dopo aver letto il numero di forme con scanf("%d", &n), ogni chiamata successiva per leggere il carattere del tipo deve saltare il carattere di nuova riga rimasto nel buffer di input. Per farlo, usa uno spazio iniziale nella stringa di formato:

scanf(" %c", &type);  // note the space before %c

Senza lo spazio iniziale, scanf leggerà il carattere di nuova riga rimasto dall’input precedente invece del carattere previsto c o r, facendo fallire senza messaggi il controllo del tipo di forma e producendo nessun output.

Provalo tu

#include <stdio.h>
#include <stdlib.h>
#include "shape.h"
#include "circle.h"
#include "rectangle.h"

int main() {
    // TODO: Leggere il numero di forme
    // TODO: Allocare array per cerchi, rettangoli e puntatori Shape*
    // TODO: Scorrere ogni forma, leggerne il tipo e le dimensioni,
    //       creare la forma e memorizzare un puntatore alla sua base nell'array shapes
    // TODO: Scorrere l'array shapes, chiamare shapes[i]->draw(...) e
    //       shapes[i]->area(...) direttamente e accumulare l'area totale
    //       (non chiamare process_shape: stampa una riga Area aggiuntiva)
    // TODO: Stampare l'area totale nel formato: Total Area: X.XX
    // TODO: Liberare la memoria allocata
    return 0;
}

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore C online