МАРК РЕГНЕРУС ДОСЛІДЖЕННЯ: Наскільки відрізняються діти, які виросли в одностатевих союзах
РЕЗОЛЮЦІЯ: Громадського обговорення навчальної програми статевого виховання ЧОМУ ФОНД ОЛЕНИ ПІНЧУК І МОЗ УКРАЇНИ ПРОПАГУЮТЬ "СЕКСУАЛЬНІ УРОКИ" ЕКЗИСТЕНЦІЙНО-ПСИХОЛОГІЧНІ ОСНОВИ ПОРУШЕННЯ СТАТЕВОЇ ІДЕНТИЧНОСТІ ПІДЛІТКІВ Батьківський, громадянський рух в Україні закликає МОН зупинити тотальну сексуалізацію дітей і підлітків Відкрите звернення Міністру освіти й науки України - Гриневич Лілії Михайлівні Представництво українського жіноцтва в ООН: низький рівень культури спілкування в соціальних мережах Гендерна антидискримінаційна експертиза може зробити нас моральними рабами ЛІВИЙ МАРКСИЗМ У НОВИХ ПІДРУЧНИКАХ ДЛЯ ШКОЛЯРІВ ВІДКРИТА ЗАЯВА на підтримку позиції Ганни Турчинової та права кожної людини на свободу думки, світогляду та вираження поглядів
Контакти
Тлумачний словник Авто Автоматизація Архітектура Астрономія Аудит Біологія Будівництво Бухгалтерія Винахідництво Виробництво Військова справа Генетика Географія Геологія Господарство Держава Дім Екологія Економетрика Економіка Електроніка Журналістика та ЗМІ Зв'язок Іноземні мови Інформатика Історія Комп'ютери Креслення Кулінарія Культура Лексикологія Література Логіка Маркетинг Математика Машинобудування Медицина Менеджмент Метали і Зварювання Механіка Мистецтво Музика Населення Освіта Охорона безпеки життя Охорона Праці Педагогіка Політика Право Програмування Промисловість Психологія Радіо Регилия Соціологія Спорт Стандартизація Технології Торгівля Туризм Фізика Фізіологія Філософія Фінанси Хімія Юриспунденкция |
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ПрикладType Begin Begin КЛЮЧОВЕ СЛОВО INHERITED ______________________________________________________ VAR P1: ^Integer; P2: ^String; Простий спосіб розміщення таких динамічних об'єктів: New ( P1 ); New ( Р2 ); ... де P1 і Р2 - імена вказівників на динамічні об'єкти. Begin New(P1); New(P2); …. End;
New може використовуватися також як функція, яка повертає значення вказівника. Наприклад: P1 := New ( Pobjname ); де Pobjname - ім'я типу вказівника динамічного об'єкту. Звернення до змінної - екземпляру об'єкту за допомогою вказівника проводиться у вигляді Р1^ або Р2^. Виклики методів проводяться звичайним способом. Наприклад: Р1^.МЕТ2; Якщо динамічний об'єкт містить віртуальні методи, він повинен ініціалізуватися за допомогою виклику конструктора. Наприклад: P1^.INIT; P2^.INIT; Якщо конструктор не може розмістити динамічний об'єкт ОП, то він повертає "порожній" вказівник, наприклад: P1 = NIL. Для роботи з динамічними об'єктами, що містять віртуальні методи, Паскаль має процедури NEW і DISPOSE з розширеними можливостями. Розширений синтаксис процедури Newдозволяє виділяти з купи ОП для об'єкту і ініціалізувати сам об'єкт за допомогою виклику його конструктора. Для цього процедура New викликається з двома параметрами: ім'ям вказівника і ім'ям конструктора. Наприклад: New (P1,init); New(P2,init);. Параметр INIT виконує виклик конструктора і ініціалізацію динамічного об'єкту. Для роботи з нетипізованими вказівниками можна використовувати процедури GetMem і FreeMem. Процедура GetMem виділяє область динамічної пам'яті заданого обсягу. Початкова адреса області пам'яті, яка буде виділена, запам'ятовується у вказівнику, що є параметром процедури. Виклик процедури GetMem має такий синтаксис:
Тут <ідентифікатор вказівника> - змінна типу pointer; <обсяг пам'яті> — змінна або вираз типу word. Обсяг пам'яті задається в байтах. Обсяг пам'яті, що виділяється для однієї динамічної змінної, не може перевищувати 65 521 байт.
Зазначимо, що загальний обсяг усіх вільних ділянок динамічної пам'яті обчислює функція MemAvail.
В попередньому прикладі ми використовували виклик предківського методу шляхом вказання імені предка, після якого пишеться крапка та ім’я конструктора. constructor TStudent1.init(nm,dt:string;rt,bl:real); IF NOT TStudent.Init(nm,dt,rt) THEN Failed; bal:=bl; end; Pascal дає можливість використовувати спеціальне слово INHERITED , використовуючи яке можна викликати методи предка без вказання імені предка. constructor TStudent1.init(nm,dt:string;rt,bl:real); IF NOT INHERITED Init(nm,dt,rt) THEN Failed; bal:=bl; end; Це може виявитися корисним при використанні великої ієрархії об’єктів, коли складно запам’ятати всі зв’язки типу «предок-потомок». 3. ВИДАЛЕННЯ ДИНАМІЧНИХ ОБ’ЄКТІВ. ______________________________________________ Динамічними можуть бути об'єкти із статичними і віртуальними методами. Видалення динамічних об'єктів може бути за допомогою процедур Dispose або за допомогою деструктора. Синтаксис виклику процедури Dispose такий:
Подібно до інших динамічних типів даних динамічні об'єкти із статичними методами можуть видалятися за допомогою Dispose. Наприклад: Dispose ( P1 ); Приклад програми з динамічним об'єктом із статичними методами даний в лістингу 1. Для звільнення ОП динамічних об'єктів з віртуальними методами використовуються особливі методи - деструктори. В якості їх імені рекомендується вживати ім'я Done. Вони призначені для виконання завершуючих дій програми. Деструктори розміщуються разом з іншими методами об'єкту у визначенні типу і оформляється так само, як звичайний метод-процедура, але слово PROCEDURE замінюється словом DESTRUCTOR. Наприклад: Destructor Tobjl.Done; Виклик деструкції (Done) поза процедурою Dispose не приведе до автоматичного звільнення ОП, займаною екземпляром об'єкту, тобто неприпустимо Р1^.Done;. Для коректного звільнення ОП, яку реально займає екземпляр динамічного об'єкту з пізнім скріпленням, деструкцію треба викликати за допомогою розширеного типу процедури Dispose. Він має 2 параметри: ім'я покажчика на об'єкт і ім'я деструкції. Наприклад: Dispose ( P1,done); де Done - ім'я деструкції об'єкту, на який указує Р1. Деструктор об’єднує етап видалення об’єкту з іншими діями чи задачами, необхідними для даного типу об’єкту. Для одного типу об’єкту можна визначити кілька деструкторів. 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. Програма ех_2 демонструє механізм роботи процедур New і Dispose, а також Mark і Release. Стан динамічної пам'яті під час роботи програми показано на рисунку. program ex_2; var ptr,p1,р2,р3,р4:^іnteger; begin New(p1); {виділити пам'ять для цілого числа } Mark(ptr); {запам'ятати адресу початку вільної області} New(p2); {виділити пам'ять ще для трьох цілих чисел } New(p3); New(p4); Dispose(p3); {звільнити пам'ять від рЗ^ } Release(ptr); {звільнити пам'ять від р2^,рЗ^, р4^ } { Dispose(p4); {помилка: змінну р4^ вже видалено!!! } readln; end. Приклад програми з динамічним об'єктом з віртуальними методами і з використанням деструкції Лістинг 2. Динамічні об'єкти з віртуальним методом. Program Dvirt; {$F+,R+} Uses Crt; Type Objname1 = object { - тип об'єкту-предка } Fl1 : integer; Constructor Met1; {- конструктор типу Objname1 } Destructor Done; Virtual; {- деструкція типу Objname1 } Procedure Met2; Virtual; End; Objname2=object (Objname1) {- тип нащадка Objname1 ) Procedure Met2; Virtual; Destructor Done; Virtual; {- деструктор типу Objname2 } End; Pobjname1 = ^ObjName1; {- тип - покажчик на об'єкт Objname1} Pobjname2 = ^ObjName2; { -" " " Objname2 } {---------------------------- Методи об'єкту Objname1---------------------------------------} Constructor Objname1.Met1; Begin Met2; {- виклик Met2 з конструктора } End; Destructor Objname1.Done; Begin Writeln ('Звільняється ОП об'єкту типу Objname1'); End; Procedure Objnamel.Met2; Begin Fl1 := 12; Writeln ('Працює метод Objname1.Met2: Fl1= ', Fl1) End; { Методи об'єкту Objname2 } Procedure Objname2.Met2; Begin Fl1 := 34; Writeln ('Працює метод Objname2.Met2: Fl1 = ', Fl1) End; Destructor Objname2.Done; Begin Writeln ('Звільняється ОП об'єкту типу Objname2'); End; Var V1 : Pobjname1; { - динамічний об'єкт V1 } V2 : Pobjname2; { - " " V2 } { Основна програма Begin Clrscr; Assign (Output, 'Dvirt.res'); Rewrite (output); Writeln ('ДИНАМІЧНІ ОБ'ЄКТИ, ВІРТУАЛЬНІ МЕТОДИ' ); Writeln ('Працюємо з V1 - екземпляром типу предка'); { Викликається конструктор Met1 для екземпляра V1 - предка:} New (V1,met1); {- створення динамічного об'єкту V1 } V1^.Met2; {- виклик методу Objname1.Met2; } { Видалення об'єкту - тільки за допомогою Dispose і Done: } Dispose (V1,done); {- видалення об'єкту V1 деструкцією Objname1.Done } Writeln ('Працюємо з V2- екземпляром типу нащадка'); { Викликається конструктор Met1 для екземпляра V2 - нащадка V1:} New ( V2, Met1 ); { - створення динамічного об'єкту V2 } V2^.Met2; {- виклик методу Objname2 .Met2; } { Видалення об'єкту - тільки за допомогою Dispose і Done: } Dispose (V2,done); { - видалення об'єкту V2 деструкцією Objname2.Done} Close (Output); End. Читайте також:
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|