69735

Віртуальні методи

Домашняя работа

Информатика, кибернетика и программирование

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

Украинкский

2014-10-09

45 KB

0 чел.

Самостійне вивчення

Тема 12: Віртуальні методи

Робота з об'єктами частіше за все проводиться через покажчики. Покажчику на базовий клас можна присвоїти значення адреси об'єкту будь-якого похідного класу, наприклад:

// Описується покажчик на базовий клас:

monstr *p;

// Покажчик посилається на об'єкт похідного класу:

р = new daemon;

Виклик методів об'єкту відбувається відповідно до типу покажчика, а не фактичним типом об'єкту, на який він посилається, тому при виконанні оператора, наприклад,

p->draw(l, 1.1, 1);

буде викликаний метод класу monstr, а не класу daemon, оскільки посилання на методи дозволяються під час компоновки програми. Цей процес називається раннім скріпленням. Щоб викликати метод класу daemon, можна використовувати явне перетворення типу покажчика:

(daemon * p)->draw(l, 1, 1, 1);

Це не завжди можливо, оскільки в різний час покажчик може посилатися на об'єкти різних класів ієрархії, і під час компіляції програми конкретний клас може бути невідомий. Можна навести як приклад функцію, параметром якої є покажчик на об'єкт базового класу. На його місце під час виконання програми може бути переданий покажчик на будь-який похідний клас. Інший приклад — зв'язний список покажчиків на різні об'єкти ієрархії, з яким вимагається працювати одноманітно.

В C++ реалізований механізм пізнього скріплення, коли дозвіл посилань на метод відбувається на етапі виконання програми  залежно від конкретного типу об'єкту, який викликав метод. Цей механізм реалізований за допомогою віртуальних методів. Для визначення віртуального методу використовується специфікатор virtual, наприклад:

virtual void draw(int x, int у, int scale, int роsition);

Правила опису і використовування віртуальних методів.

  1. Якщо в базовому класі метод визначений як віртуальний, метод  визначений в похідному класі з тим же ім'ям і набором параметрів, автоматично стає віртуальним, а з відмінним набором параметрів — звичайним.  Віртуальні методи успадковуються,  тобто перевизначати їх в похідному класі потрібно тільки при необхідності задати відмінні дії. Права доступу при перевизначенні  змінити не можна.

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

3. Якщо в класі вводиться опис віртуального методу, він повинен  бути визначений хоча б як чисто віртуальний. Чисто віртуальний метод містить ознаку - 0 замість тіла, наприклад:

virtual  void f(int)= 0;

Чисто віртуальний метод повинен перевизначатися в похідному класі (можливо, знову як чисто віртуальний).

4. Якщо визначити метод draw в класі monstr як віртуальний, рішення про те, метод якого класу викликати, ухвалюватиметься залежно від типу об'єкту, на який посилається покажчик:

monstr *r *р;

r - new monstr;                                    // Створюється об'єкт класу monstr

р - new daemon;                                    // Створюється об'єкт класу daemon

r->draw(l, 1, 1, 1);       // Викликається метод monstr::draw

p->draw(l, 1, 1, 1);       // Викликається метод daemon::draw

p-> monstr::draw(l. 1, 1, 1);    // Обхід механізму віртуальних методів

Якщо об'єкт класу daemon викликатиме метод draw не безпосередньо, а косвено (тобто з іншого методу, визначеного в класі monstr), буде викликаний метод draw класу daemon. Отже, віртуальним називається метод, посилання на який дозволяється на етапі виконання програми.

Механізм пізнього скріплення

Для кожного класу (не об'єкту!), який містить хоча б один віртуальний метод, компілятор створює таблицю віртуальних методів (vtbl), в якій для кожного віртуального методу записана його адреса в пам'яті. Адреси методів методів в таблиці в порядку їх опису в класах. Адреса будь-якого віртуального методу має в vtbl один і той же зсув для кожного класу в межах ієрархії.

Кожний об'єкт містить приховане додаткове поле посилання на vtbl, яке має назву vptr. Воно заповнюється конструктором при створенні об'єкту (для цього компілятор додає в початок тіла конструктора відповідні інструкції). На етапі компіляції посилання на віртуальні методи замінюються на звернення до vtbl через vptr об'єкту, а на етапі виконання в момент звернення до методу його адреса вибирається з таблиці. Таким чином, виклик віртуального методу, на відміну від звичайних методів і функцій, виконується через додатковий етап отримання адреси методу з таблиці. Це дещо уповільнює виконання програми.

Рекомендується робити віртуальними деструктори для того, щоб гарантувати правильне звільнення пам'яті з-під динамічного об'єкту, оскільки в цьому випадку у будь-який момент часу буде вибраний деструктор, який відповідає фактичному типу об'єкту. Деструктор передає операції delete розмір об'єкту, який має тип size_t. Якщо об'єкт який видаляється, є похідним і в ньому не визначений віртуальний деструктор, розмір об'єкту який передається може виявитися невірним.

Чіткого правила, по якому метод слідує робити віртуальним, не існує. Можна тільки дати рекомендацію оголошувати віртуальними методи, для яких є вірогідність, що вони будуть перевизначені в похідних класах. Методи, які у всій ієрархії залишаться незмінними або ті, якими похідні класи користуватися не будуть, робити віртуальними немає змісту. З другого боку, при проектуванні ієрархії не завжди можна передбачити, яким чином розширятимуться базові класи (особливо при проектуванні бібліотек класів), а оголошення методу віртуальним забезпечує гнучкість і можливість розширення.

Для пояснення останньої тези уявимо собі, що виклик методу draw робиться з методу переміщення об'єкту. Якщо текст методу переміщення не залежить від типу переміщуваного об'єкту (оскільки принцип переміщення всіх

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

Абстрактні класи

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

1.  Абстрактний клас не можна використовувати при явному приведенні типів, для опису типу параметра і типу значення яке повертається функцією;

2.   Допускається оголошувати покажчики і посилання на абстрактний клас, якщо при ініціалізації не вимагається створювати тимчасовий об'єкт;

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

Таким чином, можна створити функцію, параметром якої є покажчик на абстрактний клас. На місці цього параметра при виконанні програми може передаватися покажчик на об'єкт будь-якого похідного класу. Це дозволяє створювати поліморфні функції, які працюють з об'єктом будь-якого типу в межах однієї ієрархії.

Множинне спадкоємство

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

class monstr

{

public: int get_health():

};

class hero

{

public: int get_health();

......

};

class ostrich: public monstr, public hero

{

......

};

int main()

{

ostrich А;

cout << A.monstr::get_health();

cout << A.hero::get_health();

}

Як видно з прикладу, для виклику методу get_hea1th вимагається явно вказувати клас, в якому він описаний. Використання звичайної для виклику методу класу конструкції A.get_health() приведе до помилки, оскільки компілятор не в змозі розібратися, до методу якого з базових класів потрібно звернутися.

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

class monstr

{

......

};

class daemon: virtual public monstr

{

........

};

class lady: virtual public monstr

{

.......

};

class baby: public daemon, public lady

{

........

};

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

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


 

А также другие работы, которые могут Вас заинтересовать

28231. Способы управления эмоциями. Защитные механизмы и совладающее поведение 43.5 KB
  Защитные механизмы и совладающее поведение. Защитные механизмы психики. Отрицание Проекция Приписывает свои мотивы другим людям атрибутивнаяособзает черту и бессознателтно приписывает другим комплементарная осознает но источник лежит в другом классическая не признает качество Смешение Смещение объекта смещение влечения Регрессия объекта при разводе к маме Идентификация принимает личные характеристики другого на себя Компенсация Реактивное образование Замена на противоположные импульсы Рационализация Сублимация...
28232. Психические состояния и их классификация 31.5 KB
  Левитов: Состояние целостная характеристика психической деятельности и поведения за некоторый период времени показывающая своеобразие протекания психических процессов в зависимости от отражения объектов и явлений действительности в настоящий момент в зависимости от конкретной ситуации предшествующего состояния и психических свойств личности. Состояние целостная организация поведения и деятельности за определенный момент времени. Психическое состояние относительно устойчивое психическое явление характеризующее психику в целом фон на...
28233. Диагностические и прогностические возможности интеллектуального тестирования (краткая характеристика основных интеллектуальных) 64 KB
  В отечественной психологии интеллект рассматривается как компонент индивидуальности связанный с личностными характеристиками исследования связей интеллекта с эмоциональноволевыми особенностями социальноэкономическими условиями и т. В истории исследования генезиса интеллекта человека можно выделить 2 главных подхода взаимно обогащающих друг друга. Источник развития интеллекта в нем самом развитие представляет собой развертывание стадий операторных механизмов по сформированным природой алгоритмам. Интеллект необходимо рассматривать как...
28234. ПСИХОЛОГИЧЕСКАЯ СТРУКТУРА ЧЕЛОВЕКА (ИНДИВИД-ЛИЧНОСТЬ-ИНДИВИДУАЛЬНОСТЬ) В РАБОТАХ Б.Г.АНАНЬЕВА 32 KB
  Форма развития индивида онтогенетическая эволюция которая идет по филогенетической программе но модифицируется под влиянием социальной истории в соответствии с возрастом и индивидуальной изменчивостью: постепенно усиливается влияние социальных свойств личности. На развитие индивида накладывается развитие личности → ступени общественного воспитания образования и обучения стали определяющими характеристиками периодов развития индивида. статус личности в обществе активная позиция человека статус общности в которой формировалась личность...
28235. Развитие сознания и самосознания в онтогенезе. Функции самосознания: самопознание, саморегуляция и самоорганизация 35 KB
  Во всех видах деятельности и поведения эти отношения следуют за отношением к ситуации предмету деятельности к другим людям. Требуется накопление опыта множества подобных осознаний себя субъектом поведения для того чтобы oтношение к себе превратились в свойство называемое рефлексивностью. Чужую самооценку например родительскую; Способы регуляции поведения; 6. Самосознание культурный феномен позволяющий сохранять постоянство собственного поведения и испытывать чувство ответственности за социальные ценности усвоенные индивидом.
28236. «Образ Я» и «Я-концепция». Структура, этапы формирования, функции имеханизмы защиты 42.5 KB
  Описательная составляющая Яконцепции образ Я или картина Я; составляющая связанная с отношением к себе или к отдельным своим качествам самооценка или принятие себя. Три главных элемента Я концепции: Когнитивная составляющая образ Я представление индивида о самом себе. Составляющие Яконцепции: реальное Я представление о себе в настоящем времени идеальное Я то каким субъект по его мнению должен был бы стать ориентируясь на моральные нормы. Бернс выделяет следующие основные ракурсы Яконцепции: Реальное Я установки...
28237. Личность в системе отношений и структура отношений личности. Взгляды В.М. Бехтерева, А.Ф. Лазурского и В.Н. Мясищева 46 KB
  Личность в системе отношений и структура отношений личности. Психология отношений специфическая теория личности имеет существенное значение при исследовании проблем нормального и патологического формирования личности происхождения болезней и механизмов их развития особенностей клинических проявлений лечения и предупреждения. Одно из фундаментальных положений психологии отношений является понимание личности как системы отношений индивида с окружающей средой. Эти отношения представляют собой преимущественно сознательную основанную на...
28238. НЕЙРОТИПИЧЕСКИЕ ОСОБЕННОСТИ ЧЕЛОВЕКА (Б.М.ТЕПЛОВ, В.Д.НЕБЫЛИЦЫН, Е.П.ИЛЬИН) 68 KB
  НЕЙРОТИПИЧЕСКИЕ ОСОБЕННОСТИ ЧЕЛОВЕКА Б.ИЛЬИН Свойства НС это устойчивые особенности НС влияющие на индивидуальные психологические особенности человека. Свойства НС природные врожденные особенности НС влияющие на формирование индивидуальных форм поведения у животных и некоторых индивидуальных различий способностей и характера у человека Павлов Теплов. Тип высшей нервной деятельности генотип темперамент следует отличать от характера фенотипа или склада высшей нервной деятельности который есть сплав из черт типа и тех черт...
28239. ТЕМПЕРАМЕНТ: ЕГО СВОЙСТВА И ТИПОЛОГИЯ 31.5 KB
  эмоциональная неустойчивость врожденная склонность человека входить в состояние эмоционального напряжения тревожность степень личностного ситуативного эмоционального напряжения в угрожающей ситуации или ситуации повышенной ответственности утомляемость работоспособность врабатываемость импульсивность быстрота реакции непроизвольных движений приспособление к непосредственно действующим раздражителям быстрота принятия решения и его исполнение ригидность пластичность степень легкости приспособления к новой ситуации...