Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Не підтверджено.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
3.08 Mб
Скачать

Int mainO

{

derived ObjD(3,4);

ObjD.showB("Ba30Bnft клас:"); // Відображає числа c= 3; f= 4 getchO; return 0;

}

Конструктор похідного класу може використовувати будь-які (або всі) пара­метри, які ним оголошені для прийняття, незалежно від того, чи передаються вони (один або декілька) базовому класу. Іншими словами, той факт, що деякий аргу­мент передається базовому класу, не заважає його використанню і самим похід­ним класом. Наприклад, наведений нижче фрагмент коду програми є абсолютно допустимим:

class derived: public baseClass { int d; public:

/* Клас derived використовує обидва параметри х і у, а також передає їх класу baseClass */

derived(int х, int у): baseClass(x, у)

{d = х*у; cout«"Створення derived-об'єкта" « endl;}

//...

}

При передачі аргументів конструкторам базового класу необхідно мати на увазі, що аргумент, який передається, може містити будь-який (дійсний на момент передачі) вираз, що містить виклики функцій і змінних. Це можливо завдяки то­му, що мова C++ дає змогу виконувати динамічну ініціалізацію даних.

  1. Повернення успадкованим членам класу початкової специфікації доступу

Коли базовий клас успадковується як закритий (як private-Knac), то всі його члени (відкриті, захищені та закриті) стають private-членами похідного класу. Але за певних обставин один або декілька успадкованих членів необхідно повернути до їх початкової специфікації доступу. Наприклад, незважаючи на те, що базовий клас успадковується як private-Knac, деяким визначеним його public-членам потріб­но надати риЬІіс-статус у похідному класі. Це можна зробити двома способами:

  • по-перше, у похідному класі можна використовувати оголошення using (цей спосіб ре­комендується стандартом мови C++ для використання в новому коді програми). Але особливості використання директиви using відкладемо до розгляду теми простору імен1;

  • по-друге, можна налагодити доступ до успадкованого члена за допомогою оголошень доступу.

Зауважмо, що оголошення доступу все ще підтримуються стандартом мови C++, але останнім часом активізувалися заперечення проти його застосування, а це означає, що його не варто використовувати в новому коді програми. Позаяк во­но все ще використовуються у мові програмування C++, то дещо приділимо увагу цій темі.

Оголошення доступу має такий формат: ім'я_базового_кпасу::чпен\

Оголошення доступу відновлює рівень доступу до успадкованого члена, внаслідок чого він отримує той статус, який був у нього в базовому класі.

Оголошення доступу поміщається у похідному класі під відповідним специ­фікатором доступу. Зверніть увагу на те, що оголошення типу у цьому випадку вказувати не потрібно. Щоб зрозуміти, як працює оголошення доступу, розгляне­мо спочатку такий короткий фрагмент коду програми: class baseClass { public:

int d; // public-доступ у класі baseClass

};

// Клас baseClass успадковується як private-клас.

class derived: private baseClass { // Оголошення похідного класу

public:

// Ось механізм використання оголошення доступу: baseClass::d; // Тепер член d знову став відкритим.

//...

};

Оскільки клас baseClass успадковується класом derived закритим способом, то його public-змінна d стає private-змінною класу derived. Проте внесення цього оголо­шення доступу baseClass::d;

в класі derived під специфікатором доступу public відновлює риЬІіс-статус члена d.

Оголошення доступу можна використовувати для відновлення прав доступу public- і protected-членів. Проте для зміни (підвищення або пониження) статусу до­ступу його використовувати не можна. Наприклад, член, оголошений закритим у базовому класі, не можна зробити відкритим у похідному2. Механізм використан­ня оголошення доступу продемонстровано в такому коді програми.

Код програми 5.15. Демонстрація механізму використання оголошення доступу #include <vcl>

#include <iostream> // Для потокового введення-виведення

#include <conio> // Для консольного режиму роботи

using namespace std; // Використання стандартного простору імен

class baseClass { // Оголошення базового класу int с; // private-член у класі baseClass public:

int d, f;

void Set(int x) {c = x;} int PutO {return c;}

};

// Knac baseClass успадковується як private-клас.

class derived: private baseClass {

public:

/* Наступні три настанови перевизначають private-успадкування класу baseClass і відновлюють риЬІіс-статус доступу для членів d, Set() і PutO- *1

II Змінна d стає знову public-членом а змінна f залишається закритим членом. baseClass: :d;

baseClass::setL; // Функція SetO стає public-членом. baseClass::getC; // Функція Put() стає public-членом.

// baseClass::c; // Неправильно: не можна підвищувати рівень доступу int а; // public-член

};

int mainO

{

derived ObjD; // Створення об'єкта класу

// ObjD.c = 10; // Неправильно, оскільки член с закритий у класі derived.

ObjD.d = 20; // Допустимо, оскільки член d став відкритим у класі derived

// ObjD.f = ЗО; // Неправильно, оскільки член f закритий у класі derived.

ObjD.а = 40; // Допустимо, оскільки член а відкрито у класі derived.

ObjD.Set(IO);

cout« ObjD.PutO «""« ObjD.d «""« ObjD.a;

getchO; return 0;

}

Зверніть увагу на те, як у цьому коді програми використовуються оголошен­ня доступу для відновлення статусу public у членів d, SetO і Put(). У коментарях від­значені й інші обмеження, пов'язані із статусом доступу.

Мова програмування C++ забезпечує можливість відновлення рівня доступу для успадкованих членів, щоб фахівець міг успішно програмувати такі спеціальні ситуації, коли велика частина успадкованого класу повинна стати закритою, а ко­лишній public- або protected-статус потрібно повернути тільки декільком членам. Однак до цього засобу програмування краще вдаватися тільки у крайніх випадках.

5.7. Поняття про віртуальні базові класи

Під час успадкування декількох базових класів у С++-програму може бути внесений елемент невизначеності. Для розуміння сказаного розглянемо таку неко­ректну програму, яка містить помилку і не відкомпілюється.

Код програми 5.16. Демонстрація невизначеності під час успадкування декіль­кох базових класів

#include <vcl>

#include <iostream> // Для потокового введення-виведення

#include <conio> // Для консольного режиму роботи

using namespace std; // Використання стандартного простору імен

class baseClass { // Оголошення базового класу public: int с;

};

// Клас derivedA успадковує клас baseClass. class derivedA: public baseClass { public: intd;

};

// Клас derivedB успадковує клас baseClass. class derivedB : public baseClass {

public:

intf;

};

/* Клас derivedC успадковує обидва класи derivedA і derivedB.

Це означає, що у класі derivedC існує дві копії класу baseClass! */

class derivedC : public derivedA, public derivedB {

public:

int sum;

};