Ripasso: calcolatrice di forme
Fa parte della sezione Programmazione orientata agli oggetti del percorso C++ di Coddy. Lezione 63 di 104.
Sfida
FacileCostruiamo un calcolatore di forme che riunisce tutto ciò che hai imparato sul polimorfismo. Creerai una classe astratta Shape e implementerai forme concrete che calcolano la loro area e il loro perimetro, tutte accessibili tramite un'interfaccia comune.
Organizzerai il codice in quattro file:
Shape.h: definisci una classe astrattaShapeche funge da modello per tutte le forme. La classe base deve avere:- Un membro
std::string nameprotetto per identificare la forma - Un costruttore che inizializza il nome
- I metodi virtuali puri
area()eperimeter(), che restituisconodouble - Un metodo
getName()che restituisce il nome della forma - Un distruttore virtuale
- Un membro
Circle.h: implementa una classeCircleche eredita daShape:- Un membro privato
double radius - Un costruttore che riceve il raggio (imposta il nome a
"Circle") - Implementa
area()usando la formula: 3.14159 * radius * radius - Implementa
perimeter()usando: 2 * 3.14159 * radius
- Un membro privato
Rectangle.h: implementa una classeRectangleche eredita daShape:- I membri privati
double widthedouble height - Un costruttore che riceve larghezza e altezza (imposta il nome a
"Rectangle") - Implementa
area()come width * height - Implementa
perimeter()come 2 * (width + height)
- I membri privati
main.cpp: leggi quattro valori (ciascuno su una riga separata):- Raggio del cerchio (double)
- Larghezza del rettangolo (double)
- Altezza del rettangolo (double)
- Raggio del secondo cerchio (double)
Crea tutte e tre le forme dinamicamente e memorizzale in un array di puntatori
Shape*. Scorri l'array e, per ogni forma, stampa le sue informazioni in questo formato:<name>: Area: <area> Perimeter: <perimeter>Stampa una riga vuota tra una forma e l'altra. Al termine, libera gli oggetti allocati dinamicamente.
Per esempio, con gli input 5, 4, 6 e 3:
Circle:
Area: 78.5397
Perimeter: 31.4159
Rectangle:
Area: 24
Perimeter: 20
Circle:
Area: 28.2743
Perimeter: 18.8495Nota come la stessa logica printShapeInfo funziona per qualsiasi tipo di forma. Questo è il potere del polimorfismo. Il tuo codice elabora cerchi e rettangoli allo stesso modo tramite l'interfaccia Shape, e ogni forma sa come calcolare le proprie misure. Usa la parola chiave override su tutti i metodi sovrascritti per assicurarti che le firme delle funzioni siano corrette.
Provalo tu
#include <iostream>
#include "Shape.h"
#include "Circle.h"
#include "Rectangle.h"
using namespace std;
int main() {
// Leggi i valori in input
double circleRadius1, rectWidth, rectHeight, circleRadius2;
cin >> circleRadius1;
cin >> rectWidth;
cin >> rectHeight;
cin >> circleRadius2;
// TODO: Crea un array di puntatori Shape* con 3 elementi
// Shape* shapes[3];
// TODO: Crea le forme dinamicamente e memorizzale nell'array
// shapes[0] = new Circle(...);
// shapes[1] = new Rectangle(...);
// shapes[2] = new Circle(...);
// TODO: Scorri l'array e stampa le informazioni di ogni forma
// Formato:
// <name>:
// Area: <area>
// Perimetro: <perimeter>
// (riga vuota tra le forme, ma non dopo l'ultima)
// TODO: Libera gli oggetti allocati dinamicamente
// delete shapes[i];
return 0;
}
Tutte le lezioni di Programmazione orientata agli oggetti
1Fondamenti della programmazione orientata agli oggetti
File esterniBuild e compilazione in C++File header e file sorgenteNamespace e ambitoIntroduzione alla programmazione orientata agli oggetti in C++Classi e oggetti a confrontoIl puntatore 'this'Metodi (funzioni membro)Attributi (membri dati)Fondamenti di costruttori e distruttoriRiepilogo - Calcolatrice semplice4Proprietà delle classi
Membri di istanza e staticiGetter e setterFunzioni membro constParola chiave mutableMetodi e variabili staticiFunzioni e classi friendRiepilogo - Gestore di conti bancari7Ereditarietà
Ereditarietà di baseLivelli di accesso nell’ereditarietàOrdine di chiamata di costruttori e distruttoriRidefinizione dei metodiFunzioni virtuali e VTableEreditarietà multiplaEreditarietà virtualeRiepilogo - Gerarchia dei dipendenti2Gestione della memoria
Memoria Stack vs HeapPuntatori e riferimentiMemoria dinamica (new/delete)Puntatori intelligenti in C++RAII in C++Riepilogo - Gestore di array dinamico5Incapsulamento
Specificatori di accesso in C++Specificatori di accesso in dettaglioOccultamento delle informazioniStruct vs classClassi annidate e interneRiepilogo - Sistema di registrazione degli studenti8Polimorfismo
Polimorfismo a compile time e a runtimeOverload delle funzioniFunzioni virtuali: ripassoFunzioni virtuali pureClassi astratteProgettazione delle interfacce in C++Dynamic casting e RTTIRipasso: calcolatrice di forme11Concetti avanzati di OOP
Composizione vs ereditarietàMixin tramite CRTPIdiom PimplType ErasureEnum class e tipizzazione forteGestione delle eccezioni in OOPGerarchie personalizzate di eccezioni14Pattern di progettazione - Parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern CompositeRAII come pattern3Costruttori e distruttori
Costruttore predefinitoCostruttore con parametriCostruttore di copiaCostruttore di spostamentoListe di inizializzazione dei costruttoriCostruttori delegantiApprofondimento sui distruttoriRegola del Tre / Cinque / ZeroRipasso - classe String6Sovraccarico degli operatori
Introduzione al sovraccarico degli operatoriSovraccarico degli operatori aritmeticiSovraccarico degli operatori di confrontoOperatori di flussoSovraccarico dell'operatore di assegnazioneSovraccarico degli operatori [] e ()Operatori di conversione di tipoRipasso - Classe Matrix9Template
Template di funzioneTemplate di classeSpecializzazione dei templateTemplate variadiciBasi di SFINAE e dei trait di tipoRiepilogo - Contenitore genericoEsercitati da solo: Compilatore C++ online