Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
лекции / Лекции 1-2.docx
Скачиваний:
0
Добавлен:
11.02.2026
Размер:
142.98 Кб
Скачать

Int main () {

IntArray array;

array.m_array[16] = 2; // некорректный индекс, вследствие чего

// перезаписываем память, которой мы не владеем

Однако, если мы сделаем массив закрытым, то сможем заставить пользователя использовать функцию, которая первым делом проверяет корректность индекса:

class IntArray {

private:

int m_array[10]; // пользователь не имеет прямого доступа к этому

// члену

public:

Void setValue(int index, int value) {

// Если индекс недействителен, то не делаем ничего

if (index < 0 || index >= 10)

return;

m_array[index] = value;

}

};

Таким образом, мы защитим целостность нашей программы.

Примечание: Функция at() в std::array и std::vector делает что-то похожее!

Преимущество №3: Инкапсулированные классы легче изменить.

Рассмотрим следующий простой пример:

#include <iostream>

class Values {

public:

int m_number1;

int m_number2;

int m_number3;

};

int main () {

Values value;

value.m_number1 = 7;

std::cout << value.m_number1 << '\n';

}

Хотя эта программа работает нормально, но что произойдет, если мы решим переименовать m_number1 или изменить тип этой переменной?

Мы бы сломали не только эту программу, но и большую часть программ, которые используют этот класс Values!

Инкапсуляция предоставляет возможность изменения способа реализации классов, не нарушая при этом работу всех программ, которые их используют.

Вот инкапсулированная версия класса, приведенного выше, но которая использует методы для доступа к m_number1:

#include <iostream>

class Values {

private:

int m_number1;

int m_number2;

int m_number3;

public:

void setNumber1(int number) {m_number1 = number;}

int getNumber1() {return m_number1;}

};

int main () {

Values value;

value.setNumber1(7);

std::cout << value.getNumber1() << '\n';

}

Теперь давайте изменим реализацию класса:

#include <iostream>

class Values {

private:

int m_number [3]; // здесь изменяем реализацию этого класса

public:

// Нам нужно обновить переменные методов, чтобы заработала //новая реализация

void setNumber1(int number) {m_number [0] = number;}

int getNumber1() {return m_number [0];}

};

int main () {

// Но наша программа продолжает работать как прежде

Values value;

value.setNumber1(7);

std::cout << value.getNumber1() << '\n';

}

Обратите внимание, поскольку мы не изменяли прототипы 

каких-либо функций в открытом интерфейсе нашего класса, наша программа, использующая класс, продолжает работать без каких-либо изменений или проблем.

Преимущество №4: С инкапсулированными классами легче проводить отладку.

И, наконец, инкапсуляция помогает проводить отладку программ, когда что-то идет не по плану.

Часто причиной неправильной работы программы является некорректное значение одной из переменных.

Если каждый объект имеет прямой доступ к переменной, то отследить часть кода, которая изменила переменную, может быть довольно-таки трудно.

Однако, если для изменения значения нужно вызывать один и тот же метод, вы можете просто использовать точку останова для этого метода и посмотреть, как каждый вызывающий объект изменяет значение, пока не увидите что-то странное.