Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Документ Microsoft Office Word (2).docx
Скачиваний:
45
Добавлен:
09.02.2015
Размер:
842.69 Кб
Скачать

Инкапсуляция

Основным способом организации информации в Си++ являются классы. В отличие от типа структура (struct) языка Си, состоящей только из полей, класс (class) Си++ состоит из полей и функций-членов (member functions). Поля бывают публичными (public), защищёнными (protected) и собственными (приватными, private). В Си++ тип структура аналогичен типу класс, отличие в том, что по умолчанию поля и функции-члены у структуры публичные, а у класса - собственные.  С публичными полями можно делать снаружи класса всё, что угодно. К защищённым и собственным полям нельзя обращаться извне класса, чтобы не нарушить целостность данных класса. Попытка такого обращения вызовет ошибку компиляции. К таким полям могут обращаться только функции-члены класса (а также так называемые функции-друзья и функции-члены классов-друзей; о понятии друзей в C++ см. ниже.) Вне тела функций-членов (а также друзей) защищённые и собственные поля недоступны даже для чтения. Такая защита полей называется инкапсуляцией.  Используя инкапсуляцию, автор класса может защитить свои данные от некорректного использования. Кроме того, она задумывалась для облегчения совместной разработки классов. Имелось в виду, что при изменении способа хранения данных, если они объявлены как защищенные или собственные, не требуется соответствующих изменений в классах, которые используют измененный класс. Например, если в старой версии класса данные хранились в виде линейного списка, а в новой версии - в виде дерева, те классы, которые были написаны до изменения формата хранения данных, переписывать не потребуется, если данные были приватными или защищенными (в последнем случае - если использующие классы не были классами-наследниками), так как ни один из них этих классов не мог бы напрямую обращаться к данным, а только через стандартные функции, которые в новой версии должны уже корректно работать с новым форматом данных. Даже оператор доступа operator [] может быть определён как такая стандартная функция.  Функции-члены, как и поля, могут быть публичными, защищёнными и собственными. Публичные функции может вызывать кто угодно, а защищённые и собственные - только функции-члены и друзья.  Используя инкапсуляцию, структуру Array из предыдущего раздела можно переписать следующим образом:

class Array {

public:

void Alloc(int new_len);

void Free();

inline double Elem(int i);

inline void ChangeElem(int i, double x);

protected:

int len;

double* val;

};

void Array::Alloc(int new_len)

{if (len>0) Free(); len=new_len; val=new double[new_len];}

void Array::Free() {delete [] val; len=0;}

inline double Array::Elem(int i)

{assert(i>=0 && i<len ); return val[i];}

inline void Array::ChangeElem(int i, double x)

{assert(i>=0 && i<len); val[i]=x;}

И далее

Array a;

a.Alloc(10);

a.ChangeElem(3, 2.78);

double b = a.Elem(3);

a.Free();

Здесь массив a имеет 4 публичных функции-члена и 2 защищённых поля. Описатель inline означает, что вместо вызова функции её код подставляется в точку вызова, что решает проблему неэффективности.