Відлагодження програм з використанням віртуальних методів 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Відлагодження програм з використанням віртуальних методів



При відлагодженні програми для контролю правильності викликів віртуальних методів можна використовувати директиву компілятора $R. Якщо директива знаходиться у включеному стані {R+}, то всі виклики віртуальних методів будуть перевірятися на момент стану ініціалізації об’єкта, що виконує виклик методу. Якщо об’єкт, який виконує виклик, ще не був ініціалізований конструктором, відбудеться помилка виконання. за замовчуванням, встановлено значення {R+}

 

Розширюваність об’єктів

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

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

 

Переваги і недоліки віртуальних методів

В загальному випадку рекомендується робити методи віртуальними. Використання статичних методів має сенс, якщо потрібно здобути оптимальну швидкість часу виконання і використання пам’яті. Однак у цьому випадку втрачається можливість розширення.

Іноді при написанні програми точно невідомо, є метод віртуальним чи ні. В таких випадках краще визначити його віртуальним, особливо якщо ймовірно, що метод перекриватиметься ким-небудь з потомків, а його код повинен бути доступним і надалі

З іншого боку, необхідно пам’ятати, що коли у об’єкта є які-небудь віртуальні методи, то для цього об’єкту в сегменті даних буде створена таблиця віртуальних методів і будь-який екземпляр цього об’єкту буде з нею зв’язаний. Кожен виклик віртуального методу повинен проходити через VMT, тоді як статистичні методи викликаються безпосередньо. Хоча перегляд VMT цілком ефективний, виклик статистичного методу все-таки залишається швидшим, ніж виклик віртуального. Якщо в об’єкті нема віртуальних методів, то і VMT відсутня в таблиці даних і програма працюватиме швидше.

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

 


Тема 5. Об’єктно-орієнтоване програмування в Pascal. Вказівники і динамічна пам’ять

 

Вказівники

Типізовані вказівники

Нетипізовані вказівники

Операція розіменування

Присвоєння вказівників

Виділення і вивільнення динамічної пам’яті

Організація динамічної пам’яті

Процедура New

Процедура Dispose

Підсумок

Питання по темі

 

Вказівники

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

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

VAR Number:integer;

 

Цим рядком ми вказуємо компілятору на необхідність зарезервувати область в пам’яті, на яку ми будемо посилатися по імені Number.

Адресу, за якою розміщена змінна Number, в пам’яті можна визначити за допомогою оператора @

P1:=@Number;

чи за допомогою функції Addr.

В результаті виконання операції P 1:=@ Number; в змінну P1 буде записана адреса змінної Number.

Часто в процесі написання програми виникають ситуації, коли без застосування вказівників неможливо обійтися. Так трапляється, якщо:

1. Програма працює з великим об’ємом даних (більше 64 Кб)

2. Програма під час пам’яті використовує дані, об’єм пам’яті для збереження яких зарані невідомий (так часто трапляється при роботі з масивами)

3. В програмі використовується буфер пам’яті для тимчасового зберігання даних.

4. Ми використовуємо структуровані змінні, тобто записи, масиви чи множини, які мають різну структуру.

5. Програма використовує динамічні структури даних (стеки, однозв’язні і двозв’язні списки, черги, бінарні дерева).

 

Вказівники у Pascal-i можуть зв’язуватися з певним типом даних (типізовані вказівники) чи не зв’язуватися (нетипізовані вказівники). Ще для називання змінних цього типу використовуються терміни: посилання і reference.

 

Типізовані вказівники

Для оголошення типізованого вказівника звичайно використовується символ ^, який розміщується безпосередньо перед відповідним типом даних, наприклад:

TYPE

P1Ptr=^INTEGER;

VAR

P1:^INTEGER;

В загальному випадку:

TYPE

ІмяВказівника=^ІмяБазисногоТипу

де ІмяБазисногоТипу – будь-який ідентифікатор типу. В результаті такого визначення створені потім вказівники будуть вказувати на об’єкти базового типу, визначаючи тим самим динамічні змінні базового типу. Зараз нас особливо цікавлять вказівники на об’єкти. Синтаксис такого вказівника наступний:

TYPE

ObjType=OBJECT

END;

ObjPtr=^ObjType

 

Нетипізовані вказівники

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

VAR

P1:Pointer;

Оскільки нетипізовані вказівники не зв’язані з конкретним типом даних, їх дуже зручно використовувати для динамічного розміщення даних, структура і тип яких міняються в ході виконання програми.

 

Операція розіменування

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

program prob;

uses crt;

var I,j:integer;

ptri:^integer;

begin

i:=5;

ptri:=addr(i);

j:=ptri^;

writeln(‘j=’,j);

repeat until keypressed;

end.

 

Розіменувані вказівники на структури індексуются (у випадку масивів) чи поділяються на поля (записи, об’єкти) звичайним способом. Наприклад:

Pta^[i] – доступ до і-го елементу масиву

Ptrec^.поле – доступ до поля динамічного запису

ObjPtr^.Метод – доступ до методу динамічного об’єкта.

 

Присвоєння вказівників

Вказівнику можна присвоювати вміст іншого вказівника такого ж типу або нетипізованого вказівника, константу NIL (порожній вказівник), адресу об’єкта, визначену за допомогою функції addr. Наприклад, якщо ми оголосили такі вказівники:

Var

Pntr1,Pntr2:^Integer;

Pntr3:^Real;

Pntr:Pointer;

i:integer;

то присвоєння

Pntr1:=Nil;

Pntr1:=Pntr2;

Pntr2:=addr(i);

 

допустимі, а присвоєння

Pntr1:=Pntr3; - ні, оскільки ці змінні вказують на різні типи даних.

 



Поделиться:


Последнее изменение этой страницы: 2021-12-15; просмотров: 31; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 52.14.121.242 (0.016 с.)