Указатель 'Self'
Часть раздела Объектно-ориентированное программирование путешествия по C на Coddy. Урок 7 из 61.
В объектно-ориентированных языках, таких как Python или Java, когда вы вызываете object.method(), язык автоматически передаёт сам объект методу. В C мы должны делать это вручную, передавая указатель на struct в качестве первого аргумента.
Этот указатель обычно называют self (заимствовано из Python) или this (из C++). Он предоставляет функции доступ к данным struct, чтобы она могла читать или изменять их:
typedef struct {
int health;
} Player;
void player_take_damage(Player *self, int amount) {
self->health -= amount;
}
Указатель self — это то, что заставляет function работать как метод. Он знает, какого именно player нужно изменить. Без него function не имела бы возможности получить доступ к конкретному экземпляру struct. При вызове этой function передайте адрес своей struct:
Player hero = {100};
player_take_damage(&hero, 25);
// hero.health теперь 75
Использование указателя (вместо непосредственной передачи структуры) необходимо для внесения изменений. Если бы вы передали структуру по значению, функция получила бы копию, и все изменения были бы потеряны после возврата из функции. Указатель гарантирует, что изменения сохранятся в исходной структуре.
Задание
ЛегкоДавайте создадим модуль Timer, который отслеживает прошедшие секунды. Вы попрактикуетесь в использовании шаблона указателя "self" для изменения внутреннего состояния struct с помощью функций, действующих как методы.
Вы создадите три файла:
timer.h: Объявите structTimerс единственным членомint seconds. Также объявите две функции:timer_tick(takes указатель на Timer и добавляет указанное количество секунд) иtimer_reset(takes указатель на Timer и устанавливает seconds обратно в zero). Используйте include guards с символомTIMER_H.timer.c: Реализуйте обе функции. Функцияtimer_tickдолжна acceptTimer *selfиint amount, а затем добавлять amount к seconds таймера. Функцияtimer_resetдолжна acceptTimer *selfи устанавливать его seconds в zero.main.c: Создайте Timer, выполните над ним операции и выведите результаты.
Вы получите два целых входных значения: начальные seconds для вашего таймера и amount для добавления с помощью tick.
В вашем основном файле:
- Инициализируйте
Timerзначением начальных seconds - Вызовите
timer_tick, чтобы добавить указанное amount - Выведите текущие seconds
- Вызовите
timer_reset, чтобы сбросить таймер - Снова выведите seconds (should быть 0)
Выведите результаты в следующем формате:
After tick: {seconds}
After reset: {seconds}Например, при начальном значении 30 и добавлении 15 секунд результатом будет:
After tick: 45
After reset: 0Попробуйте сами
#include <stdio.h>
#include "timer.h"
int main() {
int initial_seconds, amount_to_add;
scanf("%d", &initial_seconds);
scanf("%d", &amount_to_add);
// TODO: Создайте Timer и инициализируйте его с initial_seconds
// TODO: Вызовите timer_tick, чтобы добавить amount_to_add секунд
// TODO: Выведите текущие секунды в формате: "After tick: {seconds}"
// TODO: Вызовите timer_reset, чтобы сбросить таймер
// TODO: Снова выведите секунды в формате: "After reset: {seconds}"
return 0;
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы модульного программирования
Заголовочные файлыСтражи включенияИсходные файлыСтатические функцииПовторение: Модульный калькулятор4Инкапсуляция
Концепция непрозрачных указателейОпределение непрозрачных структурГеттеры и сеттерыВалидация в сеттерахИтоги: Секретный ящик2Объекты и методы
Структуры как объектыУказатель 'Self'Константная корректностьУказатель против значенияВспомогательные методыИтоги: Point Manager5Проект: Простой банковский счет
Настройка проектаРеализация счета3Жизненный цикл объекта
Паттерн «Конструктор»Паттерн «Деструктор»Инициализация в стекеГлубокое копированиеПовторение: String Wrapper6Наследование через композицию
Встраивание структурПравило первого элементаДоступ к элементам родителяUpcastingПовторение: Иерархия фигур9Проект: Рисование фигур
Обзор проектаРеализация кругаРеализация прямоугольникаПолиморфное использованиеКонтейнер фигурПотренируйтесь самостоятельно: Онлайн-компилятор C