Паттерн «Конструктор»
Часть раздела Объектно-ориентированное программирование путешествия по 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);
Обратите внимание, как конструктор обрабатывает все сложные детали: выделяет память для структуры, выделяет место для строки и копирует данные. Вызывающий код лишь предоставляет начальные значения и получает готовый к использованию объект. Это инкапсулирует логику создания в одном месте, делая ваш код более чистым и менее подверженным ошибкам.
Задание
ЛегкоДавайте создадим модуль 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: 272remember, что ваш конструктор инкапсулирует всю логику создания: вызывающий код просто предоставляет начальные значения и получает полностью инициализированный объект, готовый к использованию.
Попробуйте сами
#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;
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы модульного программирования
Заголовочные файлыСтражи включенияИсходные файлыСтатические функцииПовторение: Модульный калькулятор4Инкапсуляция
Концепция непрозрачных указателейОпределение непрозрачных структурГеттеры и сеттерыВалидация в сеттерахИтоги: Секретный ящик2Объекты и методы
Структуры как объектыУказатель 'Self'Константная корректностьУказатель против значенияВспомогательные методыИтоги: Point Manager5Проект: Простой банковский счет
Настройка проектаРеализация счета3Жизненный цикл объекта
Паттерн «Конструктор»Паттерн «Деструктор»Инициализация в стекеГлубокое копированиеПовторение: String Wrapper6Наследование через композицию
Встраивание структурПравило первого элементаДоступ к элементам родителяUpcastingПовторение: Иерархия фигур9Проект: Рисование фигур
Обзор проектаРеализация кругаРеализация прямоугольникаПолиморфное использованиеКонтейнер фигурПотренируйтесь самостоятельно: Онлайн-компилятор C