Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Курс лекцій.doc
Скачиваний:
15
Добавлен:
03.11.2018
Размер:
1.12 Mб
Скачать

7.2 Правила доступу до полів даних

Сформулюємо правила доступу до полів даних та функцій-членів.

Загальні правила доступу.

1. Члени відкритого базового класу в похідному класі зберігають свою спеціфікацію доступу.

2. Відкриті члени захищеного базового класу стають захищеними в похідному класі. Закриті та захищені члени зберігають свої попередні спеціфікації доступу.

3. Всі члени закритого базового класу стають закритими в похідному класі незалежно від попередньої специфікації доступу.

Якщо специфікатор доступу опущений то вважається, що базовий клас є захищеним.

Детальні правила доступу.

Закрита частина класів.

1. Доступ в протоколі.

В протоколі класу є вільний доступ до всіх компонент цього протоколу; тобто будь-яка функція-член в будь-якому розділі опису класу має вільний доступ до будь-яких компонент протоколу класу.

2. Доступ через протокол похідного класу.

Незважаючи на те, що похідні класи наслідують всі протоколи від базових класів, похідний клас не має прямого доступу до полів даних та функцій-членів, описаних в закритому розділі базового класу. В наведеній вище схемі класи PublicPohid PrivatePohid та ProtectedPohid наслідують data1 та function1 з базового класу, але не мають прямого доступу до них навіть у протоколі. Доступ можна забезпечити через функцію, визначену в захищеній чи відкритій частинах класу Base.

3. Доступ через об’єкти(екземпляри класу). Об’єкт не має прямого доступу до своїх власних елементів. Для цього використовуються функції відкритого розділу.

4. Доступ через об’єкти public-похідного класу.

Очевидно, що екземпляри public-похідного класу не мають прямого доступу до закритої частини свого та базового класу. Якщо в класі Base визначені відкриті функції для доступу до закритих полів, то вони наслідуються public-похідними класами і можуть використовуватись об’єктами похідних класів для доступу до них.

5. Доступ через об’єкти private-похідного класу.

З загальних правил випливає, що прямого доступу немає. Навіть якщо описати функцію у відкритій частині базового класу, вона стає закритою в похідному. Проте і в цьому випадку є варіанти виходу.

a. Описати функцію для доступу до закритих даних у відкритій частині класу Base (нехай вона називається access);

b. Описати у відкритому розділі класу PrivatePohid ще одну функцію, яка вказує компілятору на можливість доступу до функції access за допомогою операції розширення області видимості (назвемо її privatefunc()):

returntype privatefunc(type aValue)

{Base::access(aValue);

}

Тоді можливий прямий доступ:

PrivatePohid a;

a.privatefunc(newValue);

Захищена частина класів.

Захищена частина класу - це дещо середнє між відкритою та закритою. Подібно до закритих членів, захищені члени доступні лише функціям-членам відкритого розділу класу. Екземпляр класу немає прямого доступу до своїх захищених даних.

Подібно до відкритих членів захищені члени наслідуються похідними класами і доступні в їх протоколах. Екземпляри похідних класів доступу до захищених даних базового класу, очевидно, не мають. В прикладі протоколи класів PublicDerived, PrivatePohid та ProtectedPohid мають прямий доступ до data2 та function2. В той же час об’єкти aPriv та aPub не мають прямого доступу до data2 , function2 та своїх закритих та захищених розділів.

Відкрита частина класів.

Протокол будь-якого похідного класу має прямий доступ до відкритої частини його базового класу. Всі екземпляри базового класу мають доступ до своєї відкритої частини.

Розглянемо ще кілька простих прикладів.

class Tbase{

protected: int x;

public: int y;

// . . . };

class Tderived: private Tbase {

public:

void f(void)

{ x=3;

// . . .}

// . . .};

В тілі функції f маємо прямий доступ до змінних x та y , але, оскільки Tbase є закритим базовим класом, статус цих змінних змінився на private. Нехай визначений ще один клас:

class Tdec:public Tderived {

public:

void g(void);

// . . .

}

Тут вже функція g() немає доступу до змінних x та y .

Припустимо, що оголошуючи клас B private-похідним від А, хочемо залишити відкритими лише окремі члени класу А. В такому випадку можна використати операцію розширення області видимості:

class B: private A

{// . . .

public:

A:: display();

};

Тоді функція display() буде мати відкритий статус в класі В (так, ніби вона визначена у відкритому розділі класу В).