|
||||||||||||||||||||||||||||||||||||||||||||
АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
КЛЮЧОВЕ СЛОВО INHERITED ______________________________________________________
В попередньому прикладі ми використовували виклик предківського методу шляхом вказання імені предка, після якого пишеться крапка та ім’я конструктора. constructor TStudent1.init(nm,dt:string;rt,bl:real); Begin IF NOT TStudent.Init(nm,dt,rt) THEN Failed; bal:=bl; end; Pascal дає можливість використовувати спеціальне слово INHERITED, використовуючи яке можна викликати методи предка без вказання імені предка. constructor TStudent1.init(nm,dt:string;rt,bl:real); Begin IF NOT INHERITED Init(nm,dt,rt) THEN Failed; bal:=bl; end; Це може виявитися корисним при використанні великої ієрархії об’єктів, коли складно запам’ятати всі зв’язки типу «предок-потомок». ВИДАЛЕННЯ ДИНАМІЧНИХ ОБ’ЄКТІВ. ______________________________________________ Динамічними можуть бути об'єкти із статичними і віртуальними методами. Видалення динамічних об'єктів може бути за допомогою процедур Dispose або за допомогою деструктора. Синтаксис виклику процедури Dispose такий:
Подібно до інших динамічних типів даних динамічні об'єкти із статичними методами можуть видалятися за допомогою Dispose. Наприклад: Dispose (P1); Приклад програми з динамічним об'єктом із статичними методами даний в лістингу 1. Для звільнення ОП динамічних об'єктів з віртуальними методами використовуються особливі методи - деструктори. В якості їх імені рекомендується вживати ім'я Done. Вони призначені для виконання завершуючих дій програми. Деструктори розміщуються разом з іншими методами об'єкту у визначенні типу і оформляється так само, як звичайний метод-процедура, але слово PROCEDURE замінюється словом DESTRUCTOR. Наприклад: Destructor Tobjl.Done; Виклик деструкції (Done) поза процедурою Dispose не приведе до автоматичного звільнення ОП, займаною екземпляром об'єкту, тобто неприпустимо Р1^.Done;. Для коректного звільнення ОП, яку реально займає екземпляр динамічного об'єкту з пізнім скріпленням, деструкцію треба викликати за допомогою розширеного типу процедури Dispose. Він має 2 параметри: ім'я покажчика на об'єкт і ім'я деструкції. Наприклад: Dispose (P1,done); де Done - ім'я деструкції об'єкту, на який указує Р1. Деструктор об’єднує етап видалення об’єкту з іншими діями чи задачами, необхідними для даного типу об’єкту. Для одного типу об’єкту можна визначити кілька деструкторів. Type TStudent=object Name:String[30]; Date:string[10]; rate:real; constructor init(nm,Dt:String;rt:real); destructor done; virtual; function GetName:string; virtual; function getdate:string; function getrate:real; procedure showname; procedure showdate; procedure showrate; end; Деструктори можна успадковувати і вони можуть бути статичними чи віртуальними. Оскільки різні програми завершення об’єктів звичайно вимагають різних типів об’єктів, рекомендується завжди визначати деструктори віртуальними, щоб для кожного типу об’єктів виконувався правильний деструктор.
Метод деструкції може бути і порожнім, оскільки основна інформація міститься не в тілі деструкції, а пов'язана з його заголовком, що містить слово Destructor. Деструктор нащадка останньою своєю дією повинен викликати відповідну деструкцію свого безпосереднього предка, щоб звільнити ОП всіх успадкованих вказівників об'єкту. Наприклад: Destructor Tobj1.Done; Begin ... INHERITED Done; End; Для коректного звільнення ОП при використанні поліморфних об'єктів також треба використовувати процедуру Dispose розширеного вигляду. Поліморфним є об'єкт, значенням якого можуть бути екземпляри різних (таких же або породжених) типів. Ці правила відносяться і до вказівників на об'єкти: об'єкт, що адресується ними, також буде поліморфним. Термін "поліморфний" означає, що компілятор, будуючи код об'єкту, під час компіляції, "не знає", який тип об'єкту буде насправді використаний. Єдине, що він "знає", - це те, що об'єкт належить ієрархії об'єктів, що є нащадками вказаного типу предка. Розміри різних об'єктів ієрархії можуть бути різні. Інформація про розмір об'єкту, що видаляється, стає доступною, для деструкції з ТВМ у момент видалення екземпляра об'єкту. ТВМ будь-якого об'єкту доступна через параметр Self, що містить адресу ТВМ, яка передається деструкції при його виклику.
Процедура FreeMem звільняє пам'ять, адресовану вказівником, який є параметром процедури. Обсяг пам'яті, що звільняється, зазначається як другий параметр процедури FreeMem. Наведемо синтаксис виклику процедури:
У результаті багатьох викликів процедур New і Dispose, а також GetMem і FreeMem динамічна пам'ять фрагментується. В ній з'являються несуміжні вільні ділянки. Щоб мати можливість звільняти динамічну пам'ять, використовуються процедури Mark і Release. Синтаксис виклику цих процедур такий:
Процедура Mark запам'ятовує поточне значення вказівника HeapPtr у вказівнику, що є параметром процедури.
Процедура Release звільняє динамічну пам'ять, починаючи від комірки, що адресується параметром процедури, до кінця динамічної пам'яті. Один виклик процедури Release знищує список усіх вільних фрагментів у динамічній пам'яті, створених викликами процедури Dispose, а також усі динамічні змінні, створені після виклику процедури Mark.
Constructor - для віртуальних методів, для створення ТВМ при використанні статичних і динамічних об'єктів. Destructor - для звільнення ОП динамічних об'єктів, що містять віртуальні методи. Лістинг 1. Динамічні об'єкти із статичними методами. Program novirt; Uses Crt; { Оголошення: } Type Objname1 = object { - об'єкту-предка } Fl1: integer; Procedure Met1; Procedure Met2; End; Objname2 = object (Objname1) { - об'єкту-нащадка } Procedure Met2; End; Pobjname1 = ^ObjName1; {- тип - покажчик на об'єкт Objname1 } Pobjname2 = ^ObjName2; { - " " " " Objname2 } { ----------------------------- Методи об'єкту Objname1-------------------------- } Procedure Objname1.Met1; Begin Met2; { - виклик тільки методу Objname1.Met2!!} End; Procedure Objname1.Met2; Begin Fl1:= 12; Writeln ('Працює метод Objname1.Met2: Fl1 = ', Fl1) End; {----------------------- Методи об'єкту Objname2-----------------------------------} Procedure Objname2.Met2; Begin Fl1:= 34; Writeln ('Працює метод Objname2.Met2: Fl1 = ', Fl1) End; Var V1: Pobjname1; { - динамічний об'єкт V1 } V2: Pobjname2; { - " " V2 } {------------------------------ Основна програма -----------------------------------} Begin Clrscr; Assign (Output, 'dnovirt.res'); Rewrite (output); Writeln ('ДИНАМІЧНІ ОБ'ЄКТИ, СТАТИЧНІ МЕТОДИ'); Writeln ('Працюємо з VI - екземпляром типу предка'); New (V1); { - створення динамічного об'єкту V1 } V1^.Met1; { - виклик методу Objname1.Met1; } Vl1.Met2; { - " " Objname1.Met2; } Dispose (V1); { - видалення об'єкту V1 } Writeln ('Працюємо з V2 - екземпляром типу нащадка'); New (V2); { - створення динамічного об'єкту V2 } V2^.Met1; { - викликає ЗАВЖДИ метод Objname1.Met2, а не Objname2.Met2 } V2^.Met2; { - виклик методу Objname2.Met2; } Dispose (V2); { - видалення об'єкту V2 } Close (Output); End. Поиск по сайту: |
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.01 сек.) |