Контейнер фигур
Часть раздела Object Oriented Programming путешествия по C на Coddy — урок 48 из 61.
Задание
ЛегкоДавайте доведем проект Shape Drawer до грандиозного финала! Вы создадите контейнер для фигур, который будет содержать смешанную коллекцию объектов Circle и Rectangle, а затем переберете их для вычисления общей площади — демонстрируя истинную мощь полиморфизма.
Опираясь на все, что вы создали до сих пор, ваш полный проект будет включать:
shape.hиshape.c: Ваш базовый интерфейс Shape и функцияprocess_shape.circle.hиcircle.c: Ваша реализация Circle с конструктором и расчетом площади.rectangle.hиrectangle.c: Ваша реализация Rectangle с конструктором и расчетом площади.main.c: Здесь происходит магия. Вы создадите массив указателейShape*, который может хранить любой тип фигуры. Заполните его смесью кругов и прямоугольников, а затем пройдите циклом по массиву, чтобы вычислить и отобразить общую площадь всех фигур вместе.
Ваша программа получит следующие входные данные:
- Количество создаваемых фигур
- Для каждой фигуры: индикатор типа (
cдля круга,rдля прямоугольника), за которым следуют ее размеры
Для каждой фигуры в вашем контейнере выведите результат работы функции draw. После обработки всех фигур выведите общую площадь с 2 знаками после запятой в формате Total Area: X.XX.
Пример с входными данными 3, затем 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Пример с входными данными 2, затем 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Ключевая идея заключается в том, что ваш массив хранит указатели Shape* — ему не важно, является ли каждый элемент на самом деле Circle или Rectangle. Когда вы перебираете их и вызываете draw и area через каждый указатель, автоматически выполняется правильная реализация в зависимости от того, как была создана каждая фигура. Это и есть полиморфизм в действии: один цикл, один интерфейс, множество вариантов поведения.
Помните, что вам нужно будет сохранять в массиве указатели на встроенные члены Shape ваших конкретных фигур. Используйте 3.14159 для π в расчетах площади круга.
Важно — чтение символа типа фигуры: После чтения количества фигур с помощью scanf("%d", &n), каждый последующий вызов для чтения символа типа должен пропускать оставшийся символ новой строки в буфере ввода. Используйте ведущий пробел в строке формата, чтобы сделать это:
scanf(" %c", &type); // обратите внимание на пробел перед %cБез ведущего пробела scanf прочитает символ новой строки, оставшийся от предыдущего ввода, вместо нужного c или r, что приведет к незаметному сбою проверки типа фигуры и отсутствию вывода.
Попробуйте сами
#include <stdio.h>
#include <stdlib.h>
#include "shape.h"
#include "circle.h"
#include "rectangle.h"
int main() {
// TODO: Считать количество фигур
// TODO: Выделить память под массивы для кругов, прямоугольников и указателей Shape*
// TODO: Пройти циклом по каждой фигуре, считать её тип и размеры,
// создать фигуру и сохранить указатель на её базу в массиве shapes
// TODO: Пройти циклом по массиву shapes, вызвать draw для каждой фигуры
// и вычислить общую площадь
// TODO: Вывести общую площадь в формате: Total Area: X.XX
// TODO: Освободить выделенную память
return 0;
}
Все уроки раздела Object Oriented Programming
1Основы модульного программирования
Заголовочные файлыСтражи включенияИсходные файлыСтатические функцииПовторение: Модульный калькулятор4Инкапсуляция
Концепция непрозрачных указателейОпределение непрозрачных структурГеттеры и сеттерыВалидация в сеттерахИтоги: Секретный ящик2Объекты и методы
Структуры как объектыУказатель 'Self'Константная корректностьУказатель против значенияВспомогательные методыИтоги: Point Manager5Проект: Простой банковский счет
Настройка проектаРеализация счета3Жизненный цикл объекта
Паттерн «Конструктор»Паттерн «Деструктор»Инициализация в стекеГлубокое копированиеПовторение: String Wrapper6Наследование через композицию
Встраивание структурПравило первого элементаДоступ к элементам родителяUpcastingПовторение: Иерархия фигур9Проект: Рисование фигур
Обзор проектаРеализация круга