Итоги: Секретный ящик
Часть раздела Object Oriented Programming путешествия по C на Coddy — урок 21 из 61.
Задание
ЛегкоДавайте создадим модуль Box, который демонстрирует полную инкапсуляцию. У вашего ящика будет три скрытых измерения — ширина, высота и глубина — доступ к которым возможен только через функции, которые вы предоставите. Это паттерн непрозрачного указателя (opaque pointer) в действии!
Вы создадите три файла:
box.h: Ваш публичный интерфейс. Объявите непрозрачный типBox, используя только предварительное объявление (forward declaration) — тело структуры остается скрытым. Объявите следующие функции:create_box— принимает три целых числа (ширину, высоту, глубину) и возвращает указатель на Boxdestroy_box— освобождает выделенную памятьget_volume— принимаетconst Box *и возвращает объем (ширина × высота × глубина)set_dimensions— принимает указатель на Box и три новых значения измерений, возвращаетint(1 в случае успеха, 0, если любое измерение отрицательное или равно нулю)
BOX_H.box.c: Определите самуstruct Boxс тремя скрытыми членами:int width,int heightиint depth. Реализуйте все четыре функции. Ваш конструктор должен выделять память и инициализировать ящик. Функцияset_dimensionsдолжна проверять, что все три значения положительны (больше нуля), прежде чем применять изменения — если хотя бы одно значение не проходит проверку, отклоните все обновление и верните 0.main.c: Продемонстрируйте работу инкапсулированного Box, создав его, проверив его объем, попытавшись изменить размеры (как на валидные, так и на невалидные) и выполнив правильную очистку памяти.
Вы получите пять входных данных: начальную ширину, начальную высоту, начальную глубину, а затем три новых измерения для попытки установки (которые могут включать недопустимые значения).
В вашем основном файле создайте Box с начальными размерами и выведите его объем. Затем попытайтесь установить новые размеры — выведите, удалось ли обновление, и итоговый объем. Наконец, освободите память ящика и подтвердите очистку.
Выводите результат в следующем формате:
Volume: {volume}
Set: {0 or 1}
Volume: {volume}
DestroyedНапример, при входных данных 2, 3, 4, 5, 5, 5, вывод будет следующим:
Volume: 24
Set: 1
Volume: 125
DestroyedПри входных данных 2, 3, 4, -1, 5, 5, вывод будет следующим:
Volume: 24
Set: 0
Volume: 24
DestroyedОбратите внимание, как валидация в set_dimensions защищает ваш ящик от недопустимых состояний — внешний код не может обойти ваши правила, потому что размеры полностью скрыты за вашим интерфейсом.
Попробуйте сами
#include <stdio.h>
#include "box.h"
int main() {
// Считать начальные размеры
int width, height, depth;
scanf("%d", &width);
scanf("%d", &height);
scanf("%d", &depth);
// Считать новые размеры для попытки изменения
int new_w, new_h, new_d;
scanf("%d", &new_w);
scanf("%d", &new_h);
scanf("%d", &new_d);
// TODO: Создать Box с начальными размерами
// TODO: Вывести начальный объем в формате: "Volume: {volume}"
// TODO: Попытаться установить новые размеры и сохранить результат
// TODO: Вывести, успешно ли прошло изменение, в формате: "Set: {0 or 1}"
// TODO: Вывести результирующий объем в формате: "Volume: {volume}"
// TODO: Уничтожить box и вывести "Destroyed"
return 0;
}
Все уроки раздела Object Oriented Programming
1Основы модульного программирования
Заголовочные файлыСтражи включенияИсходные файлыСтатические функцииПовторение: Модульный калькулятор4Инкапсуляция
Концепция непрозрачных указателейОпределение непрозрачных структурГеттеры и сеттерыВалидация в сеттерахИтоги: Секретный ящик2Объекты и методы
Структуры как объектыУказатель 'Self'Константная корректностьУказатель против значенияВспомогательные методыИтоги: Point Manager5Проект: Простой банковский счет
Настройка проектаРеализация счета3Жизненный цикл объекта
Паттерн «Конструктор»Паттерн «Деструктор»Инициализация в стекеГлубокое копированиеПовторение: String Wrapper6Наследование через композицию
Встраивание структурПравило первого элементаДоступ к элементам родителяUpcastingПовторение: Иерархия фигур9Проект: Рисование фигур
Обзор проектаРеализация круга