![]() |
Главная Случайная страница Контакты | Мы поможем в написании вашей работы! | |
|
Простим називається спадкування, при якому похідний клас має одного батька. Для різних методів класу існують різні правила спадкування — наприклад, конструктори й операція присвоювання в похідному класі не успадковуються, а деструктори успадковуються. Розглянемо спадкування класів і проблеми, що виникають при цьому, на прикладі.
Створимо похідний від класу 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. Зверніть увагу на запис функції-операції: у її тілі застосований явний виклик функції-операції присвоювання з базового класу. Щоб краще уявити собі синтаксис виклику, ключове слово operator разом зі знаком операції можна інтерпретувати як ім'я функції-операції.
Виклик функцій базового класу переважніше копіювання фрагментів коду із функцій базового класу в функції похідного. Крім скорочення обсягу коду, цим досягається спрощення модифікації програми: зміни потрібно вносити тільки в одне місце програми, що скорочує кількість можливих помилок.
Нижче перераховані правила спадкування деструкторів.
Поля, успадковані із класу monstr, недоступні функціям похідного класу, оскільки вони визначені в базовому класі як private. Якщо функціям, визначеним в daemon, потрібно працювати з цими полями, можна або описати їх у базовому класі як protected, або звертатися до них за допомогою функцій із monstr, або явно перевизначити їх у daemon так, як було показано в попередньому вище.
Розглядаючи спадкування методів, зверніть увагу на те, що в класі daemon описан метод draw, що перевизначає метод з тим же ім'ям у класі monstr (оскільки "малювання" різних персонажів, природно, виконується по-різному). Таким чином, похідний клас може не тільки доповнювати, але і коректувати поводження базового класу1. Доступ до перевизначеного методу базового класу для похідного класу виконується через ім'я, уточнене за допомогою операції доступу до області видимості (::).
Дата публикования: 2015-09-17; Прочитано: 509 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!