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


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


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


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


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


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


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


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


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


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



Просте спадкування

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

Створимо похідний від класу monstr клас daemon, додавши корисну в деяких випадках здатність думати.

enum color {red, green, blue};

// Клас monstr

class monstr{

// Сховані поля класу:

int health, ammo;

color skin;

char *name;

public:

// Конструктори:

monstr (int he = 100, int am = 10);

monstr(color sk);

monstr(char* nam);

monstr(monstr &M);

// Деструктор:

~monstr() {delete [] name:}
// Операції:

monstr &operator ++(){++health; return *this;}

monstr operator ++(int){monstr M(*this); health++; return M;

}

operator int(){return health;}

bool operator >(monstr &M){if( health > M.health) return true;

return false;}

const monstr &operator = (monstr &M){if (&M == this) return *this;

if (name) delete [] name;

if (M.name){name = new char [strlen(M.name) +1];

strcpy(name, M.name);}

else name = 0;

health = M.health; ammo = M.ammo; skin = M.skin; return *this;

// Методи доступу до полів:

int get_health() const {return health;}

int get_ammo() const {return ammo;}

// Методи, що змінюють значення полів:

void change_health(int he){ health = he;}

// Інші методи:

void draw(int x, int y, int scale, int position):

};

// Реалізація класу monstr

monstr::monstr(int he, int am);

health (he), ammo (am), skin (red), name (0){}

monstr::monstr(monstr &M){

if (M.name){

name = new char [strlen(M.name) + 1];

strcpy(name. M.name);}

else name =0;

health - M.health; ammo = M.ammo; skin = M.skin;

}

monstr::monstr(color sk){

switch (sk){

case red: health = 100; ammo = 10; skin = red; name = 0; break;

case green: health = 100; ammo = 20; skin = green; name = 0; break;

case blue: health = 100; ammo = 40; skin = blue: name = 0: break;

}

}

monstr::monstr(char *nam){

name = new char [strlen(nam) + 1];

strcpy(name, nam);

health - 100; ammo =10: skin = red;

}

void monstr::draw(int x, int y, int scale, int position)

{ /* Отрисовка monstr */ }

// Клас daemon

class daemon : public monstr{

int brain;

public:

// Конструктори:

daemon(int br = 10){brain = br;};

daemon(color sk) : monstr (sk) {brain =10;}

daemon(char *nam) : monstr (nam) {brain = 10;}

daemon(daemon &M) : monstr (M) {brain - M.brain;}

// Операції:

const daemon &operator = (daemon &M){

if (&M == this) return *this;

brain = M.brain;

monstr::operator = (M);

return *this;

}

// Методи, що змінюють значення полів:

void think;

// Інші методи:

void draw(int x, int у, int scale, int position);

};

// Реалізація класу daemon

void daemon :: think(){ /* ... */ }

void daemon :: draw(int x, int y, int scale, int position)

{/* Малювання daemon */} *

У класі daemon введене поле brain та метод think, визначені власні конструктори й операція присвоювання, а також перевизначений метод малювання draw. Всі поля класу monstr, операції (крім присвоювання) і методи getheal th, get_aramo і change_health успадковуються в класі daemon, а деструктор формується за замовчуванням. Розглянемо правила спадкування різних методів.

Конструктори не успадковуються, тому похідний клас повинний мати власні конструктори. Порядок виклику конструкторів визначається приведеними нижче правилами.

  • Якщо в конструкторі похідного класу явний виклик конструктора базово­го класу відсутній, автоматично викликається конструктор базового класу але по замовченню (тобто той, котрий можна викликати без параметрів). Це використано в першому з конструкторів класу daemon.
  • Для ієрархії, що складається з декількох рівнів, конструктори базових класів викликаються починаючи із самого верхнього рівня. Після цього виконуються конструктори тих елементів класу, що є об'єктами, у порядку їхнього оголошення в класі, а потім виконуються конструктори класу.
  • У випадку декількох базових класів їхні конструктори викликаються в порядку оголошення.
  • Якщо конструктор базового класу вимагає вказівки параметрів, він повинний бути явним чином викликаний у конструкторі похідного класу в списку ініціалізації (це продемонстровано в трьох останніх конструкторах).

Не успадковується й операція присвоювання, тому її також потрібно явно визначити в класі daemon. Зверніть увагу на запис функції-операції: у її тілі застосований явний виклик функції-операції присвоювання з базового класу. Щоб краще уявити собі синтаксис виклику, ключове слово operator разом зі знаком операції можна інтерпретувати як ім'я функції-операції.

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

Нижче перераховані правила спадкування деструкторів.

  • Деструктори не успадковуються, і якщо програміст не описав у похідному класі деструктор, то деструктор формується за замовчуванням і викликає деструктори всіх базових класів.
  • На відміну від конструкторів, при написанні деструктора похідного клас­а в ньому не потрібно явно викликати деструктори базових класів, це буде зроблено автоматично.
  • Для ієрархії класів, що складається з декількох рівнів, деструктори визиваються в порядку, строго зворотному виклику конструкторів: спочатку визива­єтся деструктор класу, потім — деструктори елементів класу, а потім де­структор базового класу.

Поля, успадковані із класу monstr, недоступні функціям похідного класу, оскільки вони визначені в базовому класі як private. Якщо функціям, визначеним в daemon, потрібно працювати з цими полями, можна або описати їх у базовому класі як protected, або звертатися до них за допомогою функцій із monstr, або явно перевизначити їх у daemon так, як було показано в попередньому вище.

Розглядаючи спадкування методів, зверніть увагу на те, що в класі daemon описан метод draw, що перевизначає метод з тим же ім'ям у класі monstr (оскільки "малювання" різних персонажів, природно, виконується по-різному). Таким чином, похідний клас може не тільки доповнювати, але і коректувати поводження базового класу1. Доступ до перевизначеного методу базового класу для похідного класу виконується через ім'я, уточнене за допомогою операції доступу до області видимості (::).




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

<== попередня сторінка | наступна сторінка ==>
Ключі доступу | Віртуальні методи

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

  

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


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