Menu
Coddy logo textTech

Паттерн «Конструктор»

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

В таких языках, как Java или C++, объекты создаются с помощью конструкторов: специальных функций, которые автоматически выделяют память и инициализируют поля. В C такой возможности нет, но мы можем имитировать её с помощью простого шаблона: функции create_.

Конструктор function в C обычно выполняет три действия: выделяет memory с помощью malloc, инициализирует все поля правильными значениями и возвращает pointer на новый объект:

typedef struct {
    char *name;
    int age;
} Person;

Person *create_person(const char *name, int age) {
    Person *p = malloc(sizeof(Person));
    p->name = malloc(strlen(name) + 1);
    strcpy(p->name, name);
    p->age = age;
    return p;
}

function возвращает pointer, потому что объект находится в куче, а не в стеке. Это означает, что он сохраняется после return из function и его можно свободно передавать. Вызывающий код использует его так:

Person *alice = create_person("Alice", 30);
printf("%s is %d years old\n", alice->name, alice->age);

Обратите внимание, как конструктор обрабатывает все сложные детали: выделяет память для структуры, выделяет место для строки и копирует данные. Вызывающий код лишь предоставляет начальные значения и получает готовый к использованию объект. Это инкапсулирует логику создания в одном месте, делая ваш код более чистым и менее подверженным ошибкам.

challenge icon

Задание

Легко

Давайте создадим модуль Book, который использует шаблон конструктора для создания объектов книг в куче. Вы попрактикуетесь в написании функции create_, которая выполняет всё выделение и инициализацию memory, возвращая готовый к использованию указатель.

Вы создадите три файла:

  • book.h: Declare структуру Book с двумя членами: char *title (указатель на динамически выделенную строку) и int pages. Также Declare функцию-конструктор create_book, которая принимает строку с названием и количество страниц, а затем возвращает указатель на вновь созданный Book. Используйте guards включения с символом BOOK_H.
  • book.c: Implement функцию create_book. Ваш конструктор должен выделить memory для самой структуры Book, затем выделить отдельную memory для строки названия (remember учесть нулевой терминатор), скопировать название в новую memory, установить поле pages и вернуть указатель на новый Book.
  • main.c: Используйте свой конструктор, чтобы создать книгу и отобразить её information.

Вы получите два входных значения: название книги (строка) и количество страниц (целое число).

В основном файле используйте create_book, чтобы создать новую книгу с provided значениями, затем выведите её information в следующем формате:

Title: {title}
Pages: {pages}

Например, для входных данных The C Programming Language и 272 результатом будет:

Title: The C Programming Language
Pages: 272

remember, что ваш конструктор инкапсулирует всю логику создания: вызывающий код просто предоставляет начальные значения и получает полностью инициализированный объект, готовый к использованию.

Попробуйте сами

#include <stdio.h>
#include <stdlib.h>
#include "book.h"

int main() {
    char title[256];
    int pages;
    
    // Прочитать ввод
    fgets(title, sizeof(title), stdin);
    // Удалить символ новой строки, если присутствует
    for (int i = 0; title[i]; i++) {
        if (title[i] == '\n') {
            title[i] = '\0';
            break;
        }
    }
    scanf("%d", &pages);
    
    // TODO: Используйте create_book для создания новой книги с предоставленными значениями
    
    // TODO: Выведите информацию о книге в требуемом формате:
    // Title: {title}
    // Pages: {pages}
    
    // TODO: Не забудьте освободить выделенную память, когда закончите
    
    return 0;
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

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

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