Menu
Coddy logo textTech

Геттеры и сеттеры

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

Когда члены класса являются private, внешний код cannot получать к ним доступ directly. Getter и setter — это общедоступные методы, которые обеспечивают контролируемый доступ к этим private-членам: getter извлекает значения, а setter изменяет их.

class Temperature {
    double celsius;    // Приватный - нельзя получить доступ напрямую
    
public:
    // Геттер - возвращает значение
    double getCelsius() const {
        return celsius;
    }
    
    // Сеттер - изменяет значение с проверкой
    void setCelsius(double value) {
        if (value >= -273.15) {    // Проверка абсолютного нуля
            celsius = value;
        }
    }
};

Настоящая сила сеттеров — в валидации.

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

Геттеры также могут преобразовывать данные перед их возвратом:

class Temperature {
    double celsius;
public:
    double getCelsius() const { return celsius; }
    
    // Вычисляемый геттер — не хранит fahrenheit, а вычисляет его
    double getFahrenheit() const {
        return celsius * 9.0 / 5.0 + 32.0;
    }
    
    void setCelsius(double value) { celsius = value; }
};

Обрати внимание на ключевое слово const у геттеров — это указывает на то, что они не изменяют объект. Сеттеры не могут быть const, поскольку их предназначение — изменять значения членов. Этот шаблон использования геттеров и сеттеров имеет фундаментальное значение для инкапсуляции, предоставляя тебе полный контроль над тем, как данные твоего class получают и изменяют.

challenge icon

Задание

Легко

Давайте создадим систему профиля игрока, которая демонстрирует, как геттеры и сеттеры обеспечивают контролируемый доступ к закрытым данным, включая проверку и вычисляемые свойства.

Вы создадите два файла, чтобы организовать свой код:

  • Player.h: определите Player class, которая управляет профилем игрового персонажа с защищённым доступом к данным. Ваша class должна содержать:
    • Закрытые члены: name (строка), level (int) и experience (int)
    • Constructor, который принимает имя и инициализирует level значением 1, а experience — значением 0
    • Getter getName(), который возвращает имя игрока
    • Getter getLevel(), который возвращает текущий уровень
    • Getter getExperience(), который возвращает текущие очки опыта
    • Setter setName(), который принимает только имена длиной не менее 3 characters; если имя invalid, оставьте current имя без изменений
    • Setter addExperience(int points), который принимает только положительные значения. Когда experience достигает или exceeds 100, игрок повышает уровень: увеличьте уровень на 1 и вычтите 100 из experience. Это может happen несколько раз, если добавлено достаточно experience.
    • Вычисляемый Getter getExperienceToNextLevel(), который возвращает, сколько ещё очков опыта нужно для достижения следующего уровня (always 100 - current experience)

    Пометьте все геттеры как const, поскольку они не изменяют объект.

  • main.cpp: продемонстрируйте работу ваших геттеров и сеттеров. Считайте из input имя игрока и количество добавляемых очков опыта (каждое значение в отдельной строке), затем:
    • Create Player с именем из input
    • Выведите "Player: <name>, Level: <level>, XP: <experience>"
    • Добавьте введённые очки опыта с помощью addExperience()
    • Снова выведите ту же строку состояния, чтобы показать обновлённое состояние
    • Выведите "XP to next level: <amount>"
    • Попробуйте изменить имя на "Al" (проверка должна fail)
    • Выведите "Name after invalid change: <name>"
    • Измените имя на "Champion" (это должно быть успешно)
    • Выведите "Name after valid change: <name>"

Ввод experience будет предоставлен в виде строки, которую вам нужно convert в целое число. Подключите файл заголовка в main.cpp с помощью #include "Player.h".

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

#include <iostream>
#include <string>
#include "Player.h"

using namespace std;

int main() {
    // Прочитать имя игрока
    string playerName;
    getline(cin, playerName);

    // Прочитать очки опыта для добавления (как string, преобразовать в int)
    string expString;
    getline(cin, expString);
    int expToAdd = stoi(expString);

    // TODO: Создать Player с введённым именем

    // TODO: Вывести начальный статус: "Player: <name>, Level: <level>, XP: <experience>"

    // TODO: Добавить введённые очки опыта с помощью addExperience()

    // TODO: Вывести обновлённую строку статуса

    // TODO: Print "XP to next level: <amount>"

    // TODO: Попытаться изменить имя на "Al" (должно не пройти валидацию)

    // TODO: Print "Name after invalid change: <name>"

    // TODO: Изменить имя на "Champion" (должно успешно)

    // TODO: Print "Name after valid change: <name>"

    return 0;
}
quiz iconПроверьте себя

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

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

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