- •Классы, Объекты и Методы
- •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;
- •Цепочки методов класса
- •Заключение
Инкапсуляция, Геттеры и Сеттеры Инкапсуляция
Переменные-члены класса по умолчанию являются закрытыми.
В объектно-ориентированном программировании
Инкапсуляция или «сокрытие информации» — это процесс скрытого хранения деталей реализации объекта.
Пользователи обращаются к объекту через открытый интерфейс.
В языке C++ инкапсуляция реализована через спецификаторы доступа.
Как правило, все переменные-члены класса являются закрытыми (скрывая детали реализации), а большинство методов являются открытыми (с открытым интерфейсом для пользователя).
Хотя требование к пользователям использовать публичный интерфейс может показаться более обременительным, нежели просто открыть доступ к переменным-членам, но на самом деле это предоставляет большое количество полезных преимуществ, которые улучшают возможность повторного использования кода и его поддержку.
Преимущество №1: Инкапсулированные классы проще в использовании и уменьшают сложность ваших программ.
С полностью инкапсулированным классом вам нужно знать только то, какие методы являются доступными для использования, какие аргументы они принимают и какие значения возвращают. Не нужно знать, как класс реализован изнутри.
Например, класс, содержащий список имен, может быть реализован с использованием динамического массива, строк C-style, std::array, std::vector, std::map, std::list или другой структуры данных.
Для использования этого класса, вам не нужно знать детали его реализации.
Это значительно снижает сложность ваших программ, а также уменьшает количество возможных ошибок.
Это является ключевым преимуществом инкапсуляции.
Все классы Стандартной библиотеки C++ инкапсулированы. Представьте, насколько сложнее был бы процесс изучения языка C++, если бы вам нужно было знать реализацию std::string, std::vector или std::cout (и других объектов) для того, чтобы их использовать!
Преимущество №2: Инкапсулированные классы помогают защитить ваши данные и предотвращают их неправильное использование.
Глобальные переменные опасны, так как нет строгого контроля над тем, кто имеет к ним доступ и как их используют.
Классы с открытыми членами имеют ту же проблему, только в меньших масштабах.
Например, допустим, что нам нужно написать строковый класс. Мы могли бы начать со следующего:
class MyString {
char *m_string; // динамически выделяем строку
int m_length; // используем переменную для длины строки
};
Эти два члена связаны: m_length всегда должен соответствовать длине строки, удерживаемой m_string.
Если бы m_length был открытым, то любой мог бы изменить длину строки без изменения m_string (или наоборот). Это точно привело бы к проблемам.
Делая как m_length, так и m_string закрытыми, пользователи вынуждены использовать методы для взаимодействия с классом.
Мы также можем сами улучшить защиту нашего класса от неправильного использования.
Например, рассмотрим класс с открытой переменной-членом в виде массива:
class IntArray {
public:
Int m_array[10];
};
Если бы пользователи могли напрямую обращаться к массиву, то они могли бы использовать недопустимый индекс:
