- •Классы, Объекты и Методы
- •Struct DateStruct {
- •Int month;
- •Int year;
- •Методы классов
- •Void print () {
- •Int main () {
- •Int main () {
- •Int main () {
- •Спецификаторы доступа public и private
- •Int year; // открыто по умолчанию
- •Int main () {
- •Int main () {
- •Int main ()
- •Структуры. Классы
- •Инкапсуляция, Геттеры и Сеттеры Инкапсуляция
- •Int m_array[10];
- •Int main () {
- •IntArray array;
- •Void setValue(int index, int value) {
- •Функции доступа (геттеры и сеттеры)
- •Int m_month;
- •Int m_year;
- •Int main () {
- •Краткий обзор l-value и r-value
- •Инициализация ссылок
- •Ссылки в качестве параметров в функциях
- •Void changeN (int &ref) {
- •Int main () {
- •Int value1;
- •Int otherValue;
- •Ссылки. Указатели
- •Конструкторы
- •Int main () {
- •Конструкторы по умолчанию
- •Конструкторы с параметрами
- •Int m_numerator;
- •Int m_denominator;
- •Int getNumerator () {return m_numerator; }
- •Int getDenominator () {return m_denominator; }
- •Копирующая инициализация
- •Уменьшение количества конструкторов
- •Неявно генерируемый конструктор по умолчанию
- •Int main () {
- •Int main () {
- •Классы, содержащие другие классы
- •Int main() {
- •Список инициализации членов класса
- •Списки инициализации членов класса
- •Int m_value1;
- •Values() {
- •Int m_value1;
- •Инициализация массивов в классе
- •Инициализация переменных-членов, которые являются классами
- •Int main() {
- •Использование списков инициализации
- •Int m_value1;
- •Int m_value1;
- •Int m_value1;
- •Порядок выполнения в списке инициализации
- •Инициализация нестатических членов класса
- •Void print() {
- •Int main() {
- •Void print() {
- •Int main() {
- •Void print() {
- •Int main() {
- •Void print() {
- •Int main() {
- •Делегирующие конструкторы
- •Void DoX() {
- •Init();
- •Init();
- •Void Init()
- •Int main() {
- •Ещё о делегирующих конструкторах
- •Деструкторы
- •Имена деструкторов
- •Пример использования деструктора на практике
- •Выполнение конструкторов и деструкторов
- •Int getId() { return m_nId; }
- •Int main() {
- •Предупреждение о функции exit()
- •Скрытый указатель this
- •Скрытый указатель *this
- •Int m_number;
- •Int getNumber() { return m_number; }
- •Int main() {
- •Указатель this всегда указывает на текущий объект. Явное указание указателя this
- •Int data;
- •Цепочки методов класса
- •Заключение
Функции доступа (геттеры и сеттеры)
В зависимости от класса, может быть уместным (в контексте того, что делает класс) иметь возможность получать/устанавливать значения закрытым переменным-членам класса.
Функция доступа — это короткая открытая функция, задачей которой является получение или изменение значения закрытой переменной-члена класса. Например:
class MyString {
private:
char *m_string; // динамически выделяем строку
int m_length; // используем переменную для длины строки
public:
int getLength() { return m_length; } // функция доступа для получения
// значения m_length
};
Здесь getLength() является функцией доступа, которая просто возвращает значение m_length.
Функции доступа обычно бывают двух типов:
геттеры — это функции, которые возвращают значения закрытых переменных-членов класса;
сеттеры — это функции, которые позволяют присваивать значения закрытым переменным-членам класса.
Вот пример класса, который использует геттеры и сеттеры для всех своих закрытых переменных-членов:
class Date {
private:
int m_day;
Int m_month;
Int m_year;
public:
int getDay () {return m_day;} // геттер для day
void setDay (int day) {m_day = day;} // сеттер для day
int getMonth () {return m_month;} // геттер для month
void setMonth (int month) {m_month = month;} // сеттер для month
int getYear () {return m_year;} // геттер для year
void setYear (int year) {m_year = year;} // сеттер для year
};
В этом классе нет никаких проблем с тем, чтобы пользователь мог напрямую получать или присваивать значения закрытым переменным-членам этого класса, так как есть полный набор геттеров и сеттеров.
В примере с классом MyString для переменной m_length не было предоставлено сеттера, так как не было необходимости в том, чтобы пользователь мог напрямую устанавливать длину.
Правило: Предоставляйте функции доступа только в том случае, когда нужно, чтобы пользователь имел возможность получать или присваивать значения членам класса.
Хотя иногда вы можете увидеть, что геттер возвращает
неконстантную ссылку на переменную-член — этого следует избегать!
Так как в таком случае нарушается инкапсуляция, позволяя вызывающей функции изменять внутреннее состояние класса вне этого же класса.
Лучше, чтобы ваши геттеры использовали тип возврата по значению или уже по константной ссылке.
Правило: Геттеры должны использовать тип возврата по значению или по константной ссылке. Не используйте для геттеров тип возврата по неконстантной ссылке.
Заключение
Инкапсуляция имеет много преимуществ, основное из которых заключается в использовании класса без необходимости понимания его реализации.
Инкапсулированные классы:
проще в использовании;
уменьшают сложность программы;
защищают данные и предотвращают их неправильное использование;
легче изменять;
легче отлаживать.
Это значительно облегчает использование классов.
Ссылки
Мы рассматривали 2 основных типа переменных:
обычные переменные, которые хранят значения напрямую;
указатели, которые хранят адрес другого значения (или nullptr), для доступа к которому выполняется операция разыменования указателя.
Ссылки — это третий тип переменных (псевдопеременных) в языке C++.
Ссылка — это тип переменной в языке C++, не являющийся объектом в первом смысле, который работает как псевдоним другого объекта или значения.
Язык C++ поддерживает 3 типа ссылок:
Ссылки на неконстантные значения (обычно их называют просто «ссылки» или «неконстантные ссылки.
Ссылки на константные значения (обычно их так и называют «константные ссылки».
В C++11 добавлены ссылки r-value.
Ссылка (на неконстантное значение) объявляется с использованием амперсанда (&) между типом данных и именем ссылки:
int value = 7; // обычная переменная
int &ref = value; // ссылка на переменную value
В этом контексте амперсанд не означает «операцию взятия адреса», он является разделителем «ссылка на».
Ссылки в качестве псевдонимов
Ссылки обычно ведут себя идентично переменным, на которые они ссылаются. В этом смысле ссылка работает как псевдоним объекта, на который она ссылается, например:
#include <iostream>
