Итоги: Калькулятор фигур
Часть раздела Объектно-ориентированное программирование путешествия по C++ на Coddy — урок 63 из 104.
Задание
ЛегкоДавайте создадим калькулятор фигур, который объединит все, что вы узнали о полиморфизме. Вы создадите абстрактный класс Shape и реализуете конкретные фигуры, которые вычисляют свою площадь и периметр, доступные через общий интерфейс.
Вы организуете свой код в четырех файлах:
Shape.h: Определите абстрактный классShape, который служит чертежом для всех фигур. Ваш базовый класс должен иметь:- Защищенный член
std::string nameдля идентификации фигуры - Конструктор, который инициализирует имя
- Чисто виртуальные методы
area()иperimeter(), которые возвращаютdouble - Метод
getName(), который возвращает имя фигуры - Виртуальный деструктор
- Защищенный член
Circle.h: Реализуйте классCircle, который наследуется отShape:- Приватный член
double radius - Конструктор, принимающий радиус (установите имя в
"Circle") - Реализуйте
area(), используя формулу: 3.14159 * radius * radius - Реализуйте
perimeter(), используя: 2 * 3.14159 * radius
- Приватный член
Rectangle.h: Реализуйте классRectangle, который наследуется отShape:- Приватные члены
double widthиdouble height - Конструктор, принимающий ширину и высоту (установите имя в
"Rectangle") - Реализуйте
area()как width * height - Реализуйте
perimeter()как 2 * (width + height)
- Приватные члены
main.cpp: Считайте четыре входных значения (каждое на отдельной строке):- Радиус круга (double)
- Ширина прямоугольника (double)
- Высота прямоугольника (double)
- Радиус второго круга (double)
Создайте все три фигуры динамически и сохраните их в массиве указателей
Shape*. Пройдите циклом по массиву и для каждой фигуры выведите информацию в следующем формате:<name>: Area: <area> Perimeter: <perimeter>Выводите пустую строку между каждой фигурой. Очистите динамически выделенные объекты по завершении.
Например, при входных данных 5, 4, 6 и 3:
Circle:
Area: 78.5397
Perimeter: 31.4159
Rectangle:
Area: 24
Perimeter: 20
Circle:
Area: 28.2743
Perimeter: 18.8495Обратите внимание, как одна и та же логика вывода информации о фигуре работает для любого типа фигуры — в этом и заключается сила полиморфизма. Ваш код обрабатывает круги и прямоугольники одинаково через интерфейс Shape, и каждая фигура знает, как рассчитать свои собственные параметры. Используйте ключевое слово override для всех переопределяемых методов, чтобы обеспечить правильность сигнатур функций.
Попробуйте сами
#include <iostream>
#include "Shape.h"
#include "Circle.h"
#include "Rectangle.h"
using namespace std;
int main() {
// Чтение входных данных
double circleRadius1, rectWidth, rectHeight, circleRadius2;
cin >> circleRadius1;
cin >> rectWidth;
cin >> rectHeight;
cin >> circleRadius2;
// TODO: Создайте массив указателей Shape* из 3 элементов
// Shape* shapes[3];
// TODO: Создайте фигуры динамически и сохраните их в массиве
// shapes[0] = new Circle(...);
// shapes[1] = new Rectangle(...);
// shapes[2] = new Circle(...);
// TODO: Пройдите циклом по массиву и выведите информацию о каждой фигуре
// Формат:
// <name>:
// Area: <area>
// Perimeter: <perimeter>
// (пустая строка между фигурами, но не после последней)
// TODO: Очистите динамически выделенные объекты
// delete shapes[i];
return 0;
}
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыСборка и компиляция C++Заголовочные файлы и файлы исходного кодаПространства имен и область видимостиВведение в ООП на C++Классы и объектыУказатель 'this'Методы (функции-члены)Атрибуты (члены данных)Основы конструкторов и деструкторовИтоги — Простой калькулятор4Свойства классов
Члены экземпляра против статическихГеттеры и сеттерыКонстантные функции-членыКлючевое слово mutableСтатические методы и переменныеДружественные функции и классыИтоги — Менеджер банковских счетов7Наследование
Основы наследованияУровни доступа при наследованииПорядок вызова конструкторов и деструкторовПереопределение методовВиртуальные функции и VTableМножественное наследованиеВиртуальное наследованиеИтоги — Иерархия сотрудников10Обзор STL
Обзор и философия STLКонтейнеры STLИтераторыАлгоритмы STLФункторы и лямбда-выраженияИтоги: частота слов13Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonFactory и Abstract FactoryПаттерн BuilderПаттерн ObserverПаттерн Strategy2Управление памятью
Стек и кучаУказатели и ссылкиДинамическая память (new/delete)Умные указатели в C++RAII в C++Итоги — Менеджер динамического массива5Инкапсуляция
Спецификаторы доступа в C++Спецификаторы доступа: подробный разборСокрытие данныхStruct против ClassВложенные и внутренние классыИтоги — Система учета студентов8Полиморфизм
Полиморфизм компиляции и времени выполненияПерегрузка функцийВиртуальные функции: повторениеЧистые виртуальные функцииАбстрактные классыПроектирование интерфейсов на C++Dynamic Casting и RTTIИтоги: Калькулятор фигур11Продвинутые концепции ООП
Композиция против наследованияМиксины через CRTPИдиома PimplСтирание типовEnum Classes и строгая типизацияОбработка исключений в ООППользовательские иерархии исключений14Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн КомпоновщикRAII как паттерн3Конструкторы и деструкторы
Конструктор по умолчаниюПараметризованный конструкторКонструктор копированияКонструктор перемещенияСписки инициализации конструктораДелегирующие конструкторыГлубокое погружение в деструкторыПравило трех / пяти / нуляПовторение — класс String6Перегрузка операторов
Введение в перегрузку операторовПерегрузка арифметических операторовПерегрузка операторов сравненияОператоры потоковПерегрузка оператора присваиванияПерегрузка операторов [] и ()Операторы преобразования типовИтоги — класс Matrix9Шаблоны
Шаблоны функцийШаблоны классовСпециализация шаблоновВариативные шаблоныОсновы SFINAE и Type TraitsИтоги — Обобщенный контейнер