Обзор проекта
Часть раздела Объектно-ориентированное программирование путешествия по C на Coddy. Урок 44 из 61.
Задание
ЛегкоДавайте заложим основу проекта Shape Drawer, создав базовую структуру Shape: интерфейс, который определяет, что может делать любая фигура, с помощью указателей на function.
Вы создадите два файла, чтобы настроить эту полиморфную систему:
shape.h: Здесь определите основной интерфейс. Сначала создайте предварительное объявление структурыShape. Затем определите два типа указателей на function:DrawFunc: принимает параметрconst Shape*и ничего не returnsAreaFunc: принимает параметрconst Shape*и returns значение типаdouble
Shape, содержащую два указателя на function:draw(типаDrawFunc) иarea(типаAreaFunc). Эта структура служит исключительно интерфейсом. Она не содержит данных, специфичных для фигуры, а только поведение.main.c: Продемонстрируйте работу интерфейса, создав простую тестовую фигуру. Implement две functions:test_draw: выводитDrawing test shapetest_area: returns42.0
Shape, свяжите его с этими тестовыми functions, а затем вызовите обе через интерфейс. Выведите результат вычисления площади с одним десятичным знаком.
Ваш вывод должен продемонстрировать, что указатели на function работают правильно:
Drawing test shape
Area: 42.0Зачем нужно предварительное объявление? Возможно, вы задаётесь вопросом, почему typedef struct Shape Shape; появляется до полного определения структуры. Это необходимо, потому что DrawFunc и AreaFunc ссылаются на const Shape* в типах своих параметров, но в этот момент компилятор ещё не видел полного определения структуры. Предварительное объявление сообщает компилятору: "a struct named Shape exists,", чего достаточно для использования указателя на неё. Полное определение следует позже. Этот шаблон часто используется в C, когда структуре нужно ссылаться на саму себя — напрямую или через указатели на functions.
Главная идея заключается в том, что Shape ничего не знает о кругах или прямоугольниках. Она знает только, что любая фигура должна уметь выполнять draw для себя и вычислять свою area. В следующих уроках вы создадите конкретные фигуры, которые будут включать эту базовую структуру и предоставлять собственные реализации. Не забудьте использовать защиту от повторного включения в своём заголовочном файле.
Попробуйте сами
#include <stdio.h>
#include "shape.h"
// TODO: Реализуйте функцию test_draw
// - Принимает параметр const Shape*
// - Prints "Drawing test shape"
void test_draw(const Shape* shape) {
// TODO: Выведите требуемое сообщение
}
// TODO: Реализуйте функцию test_area
// - Принимает параметр const Shape*
// - Возвращает 42.0
double test_area(const Shape* shape) {
// TODO: Верните тестовое значение площади
}
int main() {
// TODO: Создайте экземпляр Shape
// TODO: Свяжите shape с функциями test_draw и test_area
// TODO: Вызовите draw через интерфейс
// TODO: Вызовите area через интерфейс и выведите с одним знаком после запятой
// Формат: "Area: %.1f\n"
return 0;
}
Все уроки раздела Объектно-ориентированное программирование
1Основы модульного программирования
Заголовочные файлыСтражи включенияИсходные файлыСтатические функцииПовторение: Модульный калькулятор4Инкапсуляция
Концепция непрозрачных указателейОпределение непрозрачных структурГеттеры и сеттерыВалидация в сеттерахИтоги: Секретный ящик2Объекты и методы
Структуры как объектыУказатель 'Self'Константная корректностьУказатель против значенияВспомогательные методыИтоги: Point Manager5Проект: Простой банковский счет
Настройка проектаРеализация счета3Жизненный цикл объекта
Паттерн «Конструктор»Паттерн «Деструктор»Инициализация в стекеГлубокое копированиеПовторение: String Wrapper6Наследование через композицию
Встраивание структурПравило первого элементаДоступ к элементам родителяUpcastingПовторение: Иерархия фигур9Проект: Рисование фигур
Обзор проектаРеализация кругаРеализация прямоугольникаПолиморфное использованиеКонтейнер фигурПотренируйтесь самостоятельно: Онлайн-компилятор C