Наследяване в С++. Единично публично наследяване
- В С++ е реализирано, както единично така и множествено наследяване като се допуска наследяване както полета, така и на методи (в тази лекция ще раз-глеждаме само единично наследяване)
- Синтаксис:
Class <име_на_клас>: <списък_класове_предшественици>
{ private: // частна секция
<декларации на променливи и функции>;
public: // публична секция
<декларации на променливи и функции>;
protected: //секция с ограничен достъп
<декларации на променливи и функции>;
};
– пред името на всеки предшественик може да има атрибутът за достъп (private, public, protected) и ключовата дума virtual
– ако е пропуснат атрибута за достъп се подразбира private
– ако в <списък_класове_предшественици> има само едно име на клас, то е зададено единично наследяване
Семантика:
– Наследникът наследява всички полета и обикновените методи на предшественика (макар че някои от тях може да не са достъпни в наследяващия клас)
– Структурата на наследника се състои от 2 вложени блока, като блокът на наследника е вложен в този на предшественика
– Атрибутът за достъп определя какъв е достъпът до наследените членове (на този етап ще считаме, че е public !!!)
– Публично наследяване: Форма на наследяване, при която производният клас наследява характеристиките на своя предшественик(ци) по такъв начин, че тези характеристики запазват правата си за достъп, такива каквито те са били в предшественика
– Производният клас не наследява:
- конструктори
- деструктори
- приятелски функции
- статични членове-данни и членове-функции
- предефинирани операции за присвояване и new
Описание на методите на класовете-наследници
– подчинява се на общите правила за описание на методи
– при описание на методите на клас-наследник са достъпни всички негови характеристики и характеристиките на всички негови предшественици, които не са частни (private)
– достъп до предефиниран член (в този случай важи правилото за област на действие на имената в MS Visual С++):
- достъп до версията на предефинирания член от самия наследник – просто се указва неговото име
- достъп до версията на предефинирания член от някой негов предшественик – използва се синтаксисът за уточнено име (операцията за област на действие)
Задача: Какъв ще бъде резултатът от изпълнение на метода Print за екземпляр на класа Contact, ако той е описан по следния начин:
void Contact:: Print(void)
{Print();
cout << myAddress << endl;
}
Наследяване на полета и методи при публично наследяване (виж горния пример)
- При наследяване на полетата може да се изразят:
- чисто наследяване
- скриване – класът Contact няма достъп до полето myName на своя предшественик Name
- добавяне – класът Contact добавя полето myAddress към структурата наследена от предшественика си Name
- предефиниране
- При наследяване на методи е възможно:
- чисто наследяване – Contact наследява метода SetName() от своя предшественик
- добавяне – Contact добавя метода SetAddress() към функционалността наследена от предшественик
- предефиниране на методи – Contact предефинира метода Print(), с което се променя наследеното от предшественика поведение за извеждане на екрана
- скриване
Обработка на екземпляри: Активиране на конструктора на предшественика
- Правило: Активирането на конструктора на предшественика се извършва като в дефиницията на конструктора на наследника се включи т.н. инициализиращ списък. Използва се следният синтаксис:
<заглавие на конструктора> : <инициализиращ_списък>
{ <тяло_на_конструктора>}
- Синтаксис на <инициализиращ_списък>: Изброяване на извиквания на конструкторите на някои от основните класове. В случай на единично наследяване инициализиращия списък съдържа извикване на конструктора на единствения базов клас:
<име_на_базов_клас> (<списък_изрази>)
– <списък_изрази> задава фактическите параметри за активиране на конструктора на базовия клас
– фактическите параметри за активиране на конструктора на базовия клас обикновено са параметри от списъка с формални параметри на конструктора на наследника
Обработка на екземпляри: Унищожаване на обекти-наследници. Активиране на деструктора на предшественика
При унищожаване на автоматични обекти-наследници (при излизане от областта на действие на обекта) настъпват следните действия:
- Деструкторите се извикват по ред, обратен на този на активиране на конструкторите
– най-напред за обекта се извиква деструктора на наследника
– след това се активира(т) деструктора(ите) на предшествениците
- Накрая се освобождава цялата памет заета от обекта