Студопедия
Новини освіти і науки:
МАРК РЕГНЕРУС ДОСЛІДЖЕННЯ: Наскільки відрізняються діти, які виросли в одностатевих союзах


РЕЗОЛЮЦІЯ: Громадського обговорення навчальної програми статевого виховання


ЧОМУ ФОНД ОЛЕНИ ПІНЧУК І МОЗ УКРАЇНИ ПРОПАГУЮТЬ "СЕКСУАЛЬНІ УРОКИ"


ЕКЗИСТЕНЦІЙНО-ПСИХОЛОГІЧНІ ОСНОВИ ПОРУШЕННЯ СТАТЕВОЇ ІДЕНТИЧНОСТІ ПІДЛІТКІВ


Батьківський, громадянський рух в Україні закликає МОН зупинити тотальну сексуалізацію дітей і підлітків


Відкрите звернення Міністру освіти й науки України - Гриневич Лілії Михайлівні


Представництво українського жіноцтва в ООН: низький рівень культури спілкування в соціальних мережах


Гендерна антидискримінаційна експертиза може зробити нас моральними рабами


ЛІВИЙ МАРКСИЗМ У НОВИХ ПІДРУЧНИКАХ ДЛЯ ШКОЛЯРІВ


ВІДКРИТА ЗАЯВА на підтримку позиції Ганни Турчинової та права кожної людини на свободу думки, світогляду та вираження поглядів



Множинне спадкування

Якщо в похідного класу є декілька базових класів, то таке успадкування називають множинним спадкуванням. Множинне спадкування дозволяє сполучити в одному похідному класі властивості і поводження декількох класів.

Синтаксис оголошення похідного класу при множинному спадкуванні має такий вигляд:

//Базовий клас Basel

class Basel

{

//…

};

//Базовий класс Base2

class Base2

{

//…

};

//Базовий клас BaseN

class BaseN

{

//…

};

//Похідний клас Derived

class Derived :<специфікатор_доступу> Base l,

<специфікатор_доступу> Base2,

…,

<специфікатор доступу> BaseN

{

//…

};

Рисунок 2. Зображення графів множинного спадкування

 

3 Види спадкування (за специфікатором успадкованого доступу)

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

Таблиця 1. Успадкований доступ

Специфікатор успадкованого доступу Доступ у базовому класі Доступ у похідному класі
Public (зовнішнє спадкування) Public Protected Private public protected недоступні
Protected (захищене спадкування) Public Protected Private Protected Protected недоступні
Private (внутрішнє спадкування) Public Protected Private Private Private недоступні

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

class Base

{

int х, у;

public:

int GetX(){return x;}

int GetY<){return y;}

};

class Derived : private Base

{

public:

Base::GetX;

};

main ( )

{

int x;

Derived ob;

X= ob. Get ();

return 0;

}

Таким чином, при внутрішньому спадкуванні відкриті і захищені члени базового класу будуть доступні тільки для членів даного похідного класу, і всі члени базового класу, крім явно оголошених у розділі public або protected, будуть закритими для наступних похідних класів. Цей прийом дозволяє відітнути доступ до членів базового класу при побудові ієрархії класів з відношенням батько — нащадок.

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

Як ми раніше уже відзначали, не всі члени класу успадковуються. Для зручності ми перелічимо тут не успадковані члени класу:

· конструктори;

· деструктори;

друзі класу.

 

4 Віртуальне спадкування

У складній ієрархії класів при множинному спадкуванні може вийти так, що похідний клас непрямо успадкує два або більше екземпляри того самого класу. В такому випадку при компіляції виникнуть помилки, які викликаються неоднозначністю звертання до членів класу. Щоб уникнути цієї неоднозначності, можна використовувати кваліфікацію імен, застосувавши операцію дозволу видимості.

Розглянемо приклад, який прояснить цю ситуацію:

сlass IndBase

{

private;

int x;

public:

int GetX( 0 {return x;}

void SetX (int x1) {x=x1;)

double var;

};

class Base1:public IndBase

{

//…

};

class Base2:public IndBase

{

//…

};

class Derived: public Base1, public Base2

{

//…

};

main ( )

{

Derived ob;

ob.var = 5.0;

ob.SerX(0);

int z = ob.SetX();

//ob.Base1::var = 5.0;

//ob.Base1::SetX(0);

//int z = ob.Base1::GetX();

 

return 0;

}

Тутклас Derived непрямо успадковує клас IndBase через свої базові класи Base1 та Base2. Тому при компіляції наведеного прикладу виникнуть помилки, викликані неоднозначністю звертання до членів класу var та GetX() в стрічках:

ob.var = 5.0;

ob.SetX(0);

int z = ob.SetX();

Щоб уникнути цієї неоднозначності, можна використовувати кваліфікацію імен, застосувавши операцію розширення області видимості:

ob.Base1:: var = 5.0;

ob.Base1:: SetX(0);

int z = ob.Base1:: GetX( );

Можна також кваліфікувати ці виклики наступним чином:

ob.Base2:: var = 5.0;

ob.Base2:: SetX(0);

int z = ob.Base2:: GetX( );

 

Хоча цей спосіб і дозволяє уникнути неоднозначності при виклику, проте IndBase клас буде включений до складу Derived класу двічі. Уникнути повторного включення непрямого базового класу в похідний клас можна, давши вказівку компілятору використовувати віртуальний базовий клас. Це здійснюється за допомогою ключового слова virtual, що вказується перед специфікатором успадкованого доступу або після нього. Наступний приклад використовує клас IndBase у якості віртуального базового класу.

class IndBase

{

private:

int x;

 

public:

int GetX ( ) { return x ; }

void SetX(int _x) {x = _x;)

double var;

};

 

class Basel: virtual public IndBase

{

//…

};

 

class Base2: virtual public IndBase

{

//…

};

 

class Derived: public Basel, public Base2

{

//…

};

 

main ( )

{

Derived ob;

ob . var = 5.0;

ob.SetX(O) ;

int z = ob.GetXO ;

 

return 0;

}

У цьому випадку клас Derived містить один екземпляр класу IndBase і виклики

ob.var = 5.0;

ob.SetX(O);

int z = ob.GetXO ;

не приводять до появи повідомлень компілятора про помилки, пов'язаних з неоднозначністю.

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

 

Контрольні запитання

1. Яким чином створюється ієрархія класів, для чого вона потрібна і чи потрібна взагалі?

2. Яке спадкування доцільно використовувати, а яке не принесе бажаних результатів?

3. Які визначення, почуті на занятті, потрібно знати для реалізації ієрархії класів?

4. Які існують види спадкування?

5. Для чого створюється віртуальний базовий клас?

 


Читайте також:

  1. Аутосомно_рецесивний тип успадкування.
  2. Здійснення права на спадкування. Оформлення права на спадщину.
  3. Зчеплене успадкування.
  4. Зчеплене успадкування.
  5. Крок 1. Успадкування батьківських методів.
  6. Особливості спадкування за законом
  7. Поняття спадкового права. Порядок спадкування.
  8. Поняття спадкового права. Спадкування.
  9. Поняття спадкування
  10. Поняття спадкування, час і місце відкриття спадщини.
  11. Поняття спадкування. Види спадкування




Переглядів: 2793

<== попередня сторінка | наступна сторінка ==>
Просте спадкування | Автоматизація за напрямами

Не знайшли потрібну інформацію? Скористайтесь пошуком google:

  

© studopedia.com.ua При використанні або копіюванні матеріалів пряме посилання на сайт обов'язкове.


Генерація сторінки за: 0.023 сек.