Геттеры и сеттеры
Часть раздела Объектно-ориентированное программирование путешествия по 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 получают и изменяют.
Задание
ЛегкоДавайте создадим систему профиля игрока, которая демонстрирует, как геттеры и сеттеры обеспечивают контролируемый доступ к закрытым данным, включая проверку и вычисляемые свойства.
Вы создадите два файла, чтобы организовать свой код:
Player.h: определитеPlayerclass, которая управляет профилем игрового персонажа с защищённым доступом к данным. Ваша 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 достигает или exceeds100, игрок повышает уровень: увеличьте уровень на 1 и вычтите 100 из experience. Это может happen несколько раз, если добавлено достаточно experience. - Вычисляемый Getter
getExperienceToNextLevel(), который возвращает, сколько ещё очков опыта нужно для достижения следующего уровня (always100 - 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>"
- Create
Ввод 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;
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыСборка и компиляция C++Заголовочные файлы и файлы исходного кодаПространства имен и область видимостиВведение в ООП на C++Классы и объектыУказатель 'this'Методы (функции-члены)Атрибуты (члены данных)Основы конструкторов и деструкторовИтоги — Простой калькулятор4Свойства классов
Члены экземпляра против статическихГеттеры и сеттерыКонстантные функции-членыКлючевое слово mutableСтатические методы и переменныеДружественные функции и классыИтоги — Менеджер банковских счетов7Наследование
Основы наследованияУровни доступа при наследованииПорядок вызова конструкторов и деструкторовПереопределение методовВиртуальные функции и VTableМножественное наследованиеВиртуальное наследованиеИтоги — Иерархия сотрудников10Обзор STL
Обзор и философия STLКонтейнеры STLИтераторыАлгоритмы STLФункторы и лямбда-выраженияИтоги: частота слов13Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonFactory и Abstract FactoryПаттерн BuilderПаттерн ObserverПаттерн Strategy2Управление памятью
Стек и кучаУказатели и ссылкиДинамическая память (new/delete)Умные указатели в C++RAII в C++Итоги — Менеджер динамического массива5Инкапсуляция
Спецификаторы доступа в C++Спецификаторы доступа: подробный разборСокрытие данныхStruct против ClassВложенные и внутренние классыИтоги — Система учета студентов8Полиморфизм
Полиморфизм компиляции и времени выполненияПерегрузка функцийВиртуальные функции: повторениеЧистые виртуальные функцииАбстрактные классыПроектирование интерфейсов на C++Dynamic Casting и RTTIИтоги: Калькулятор фигур11Продвинутые концепции ООП
Композиция против наследованияМиксины через CRTPИдиома PimplСтирание типовEnum Classes и строгая типизацияОбработка исключений в ООППользовательские иерархии исключений14Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн КомпоновщикRAII как паттерн3Конструкторы и деструкторы
Конструктор по умолчаниюПараметризованный конструкторКонструктор копированияКонструктор перемещенияСписки инициализации конструктораДелегирующие конструкторыГлубокое погружение в деструкторыПравило трех / пяти / нуляПовторение — класс String6Перегрузка операторов
Введение в перегрузку операторовПерегрузка арифметических операторовПерегрузка операторов сравненияОператоры потоковПерегрузка оператора присваиванияПерегрузка операторов [] и ()Операторы преобразования типовИтоги — класс Matrix9Шаблоны
Шаблоны функцийШаблоны классовСпециализация шаблоновВариативные шаблоныОсновы SFINAE и Type TraitsИтоги — Обобщенный контейнерПотренируйтесь самостоятельно: Онлайн-компилятор C++