Menu
Coddy logo textTech

Обзор проекта

Часть раздела Объектно-ориентированное программирование путешествия по C на Coddy. Урок 44 из 61.

challenge icon

Задание

Легко

Давайте заложим основу проекта Shape Drawer, создав базовую структуру Shape: интерфейс, который определяет, что может делать любая фигура, с помощью указателей на function.

Вы создадите два файла, чтобы настроить эту полиморфную систему:

  • shape.h: Здесь определите основной интерфейс. Сначала создайте предварительное объявление структуры Shape. Затем определите два типа указателей на function:
    • DrawFunc: принимает параметр const Shape* и ничего не returns
    • AreaFunc: принимает параметр const Shape* и returns значение типа double
    Наконец, определите саму структуру Shape, содержащую два указателя на function: draw (типа DrawFunc) и area (типа AreaFunc). Эта структура служит исключительно интерфейсом. Она не содержит данных, специфичных для фигуры, а только поведение.
  • main.c: Продемонстрируйте работу интерфейса, создав простую тестовую фигуру. Implement две functions:
    • test_draw: выводит Drawing test shape
    • test_area: returns 42.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;
}

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор C