Под инкапсуляцией понимается скрытие или помещение в капсулу некоторых данных, определяющих свойства и поведение объекта. Иными словами, инкапсуляция означает, что функции-элементы и структуры данных, определяющие свойства данного класса, рассматриваются в качестве единого целого. Это подразумевает «защиту» данных в пределах класса таким образом, что только элементы класса получают к ним доступ. В объектно-ориентированном программировании единицей инкапсуляции является объект. В объектно-ориентированном программировании считается хорошим тоном закрывать все данные и функции-элементы описываемого класса от доступа «извне».
Компилятор C++ предоставляет программистам три уровня доступа к элементам объектов:
1) public (общедоступный);
2) private (закрытый);
3) protected (защищенный).
Элементы, объявленные общедоступными, будут доступны любому внешнему элементу класса, любой функции, элементу или выражению в программе, когда объект является видимым. Закрытые элементы доступны только членам – элементам своего же класса. Они не доступны извне, за исключением специальных функций, называемых "дружественными". К защищенным элементам имеют доступ лишь некоторые из объектов. Они доступны только элементам своего класса и любым его потомкам. Поэтому защищенные элементы занимают промежуточное положение между общедоступными и закрытыми.
Примечание: закрытые элементы не доступны потомкам своего класса, поэтому и понадобились защищенные элементы.
Одно из преимуществ инкапсуляции в том, что она позволяет разработчику класса проверить правильность любых значений, присваиваемых переменным-членам, и тем самым предотвратить ошибки программирования.
Другое преимущество управления доступом к внутренним структурам данных заключается в том, что автор класса может свободно изменить способ представления этих данных, не изменяя другие части программы, использующие класс (до тех пор, пока сохраняется интерфейс вызовов общедоступных функций-членов).
Таким образом, умелое использование уровней доступа повышает надежность программ и их способность к изменениям, ослабляя взаимозависимость между объектами. Правильно описанными функциями-элементами типа public можно изменять закрытые элементы, не затрагивая программный код других объектов. В реальной жизни мы подобным образом взаимодействуем с различными предметами: телевизором, будильником, радиоприемником, автомобилем. Знать внутреннее устройство их нам необязательно, однако нам важны внешние кнопки и ручки управления изделия.
Определение класса включает две части:
1) заголовок класса, состоящий из ключевого слова class и имени класса;
2) тело класса, заключенное в фигурные скобки и заканчивающееся точкой с запятой.
В качестве примера, приведем класс Stack, созданный на основе предыдущих ей структуры и функций, реализующей свойство инкапсуляции.
Пример 2
// Defines the entry point for the console application.
#include "stdafx.h"
#include<string.h>
#include <iostream.h>
const int MAXSIZE = 20;
const char * msg[ ] = { "Переполнение стекаn","Стек пустn "};
enum boolean { FALSE, TRUE };
class Stack
{
private:
char s[MAXSIZE];
int top;
public:
void Err_rep(int e_num) { cout << msg[e_num]; } // Сообщение об ошибке
void Reset() { top = 0; } // Очистить стек
boolean Push(char c) // Поместить символ в стек
{
if (top == MAXSIZE-1)
{
err_rep(0);
return FALSE;
}
s[top++] = c;
return TRUE;
}
char Pop() // извлечь символ из стека
{
f (top == 0)
{
err_rep(1);
return FALSE;
}
return (s[—top]);
}
};
int main(int argc, char* argv[ ])
{
char * ptr="stroka simvolov";
Stack q;
q.Reset();
for (int i=0; i< strlen(ptr); i++) q.Push(*(ptr+i));
for (i=0; i< strlen(ptr); i++) cout<<q.Pop();
cout<<endl;
return 0;
}
Следует обратить внимание на закрытые и общедоступные переменные и функции, а также на доступ к ним функций-членов, объединенных в одну «капсулу» – класс.