New кеңейтілген синтаксисі. Жадыны коррект босату

Объекттердің көрсеткіштерімен ыңғайлы жұмыс істеу үшін Паскаль тілін дайындаушылар динамикалық жадыда объекттерді тудыратын New процедурасының синтаксисін біршама өзгертті.

New көрсеткіш-типтің функциясы ретінде шақырылуы мүмкін, тип-көрсеткіш арқылы адрестелген экземплярдың көрсеткішін қайтарады(кез-келген тип үшін, объектілі тип болуы шарт емес).

New-ң қосымша параметрі болуы мүмкін – объекттің құрылған экземплярын инициализация жасау үшін конструкторды нақты параметрлерін көрсетіп, шақыру.

 Мысал. Жарияланған:

type TMyObject = object

constructor init(x,y:integer);

end;

PMyObject = ^TMyObject;

var MyObject: PMyObject;

New-дің бұрыннан қолданылып келе жатқан түрі:

new(MyObject);

MyObject^.init(10,20);

Функция ретінде(тек қана объекттермен емес!):

MyObject := new(PMyObject);

 Конструктормен қолданылуы:

new(MyObject, Init(10,20));

 Конструктормен функция ретінде қолданылуы

MyObject := new(PMyObject, Init(10,20));

Соңғысы барлығынан артығырақ – ықшамды жазу, дайын объекттің тудыруы және инициализациясы және қосымша кейінірек қарастырылатын мүмкіндіктері бар. Бұдан бөлек, соңғы әдіс Дельфидегі объекттердің тудырылуына ұқсас.

  1. Жадыны коррект босату мәселесі

Паскалда динамикалық жадыны бөлу және босату құралы мынадай екені белгілі:

New(p) – Dispose(p)

GetMem(p,size) – FreeMem(p,size)

Шындығында, New мен GetMem бірдей, Dispose бенFreeMem бірдей: компилятор бір ғана кодты шақырады, оны шақыру кезінде стекке екі параметр–инициалицазиялау үшін көрсеткіш адресі және бөлінетін жады блогының өлшемі енгізіліп қойылады.Бірақ New жәнеDispose жағдайында жады блогының өлшемі программист арқылы берілмейді, оны компилятор көрсеткіштің қалай жариялануына байланысты анықтайды.

varp:^T;

New(p) мен GetMem(p,SizeOf(T)) бірдей

Dispose(p) мен FreeMem(p,SizeOf(T)) бірдей

Бәрінен бұрын ОБП-ң артықшылықтары түрлі объекттердің біртипті басқарылуын назарда тұтатын мәселелерде айқын білінеді.

Мысал қарастырайық. Экрандық форма түрлі басқару органдарына ие. Алайда, олардың барлығы қайсыбір абстрактілі «басқару органының» әртүрлілігі(ішкікласстардың экземпляры) болып табылады. Барлық бағынышты басқару органдарын басқару үшін форма Controls көрсеткіштер массивіне ие. Егер бұл тілде типтендірілу бар болса(Паскаль), онда көрсеткіштер барлық басқару органдарының TControl жалпы абстрактілі аталығына көрсеткіш ретінде жарияланады. Бірақ, аталық класс абстрактілі болғандықан көрсеткіштер шын мәнінде реал басқару органдарының экземплярына көрсетеді: батырмаларға, жалаушаларға, жазбаларға, т.б.

Экрандық форманың стандартты әрекеттерінің бірі мынадай: форманы жойған кездеформада орналасқан барлық басқару органдары жойылуы тиіс.

Controls массивінің көрсеткіші арқылы адрестелген объекттің реал өлшемінқалай анықтауа болады?Олардың типі – абстрактілі аталыққа көрсеткіш, ал ұрпақтары өлшемі аталығынан әлдеқайда үлкен.

Объект экземплярының өлшемі VMT-да сақталынуының арқасында жадыны коррект босатуға мүмкіндік бар. Ол жерден экземпляр өлшемін екі жолмен алуға болады.

1) SizeOf (псевдо)функциясы (параметрім-объект экземпляры) VMT-н оқып, экземпляр өлшемін қайтарады. VMT-ны VMT өрісінің мәні арқылы табады. Сондықтан, былай жазуға болады:

FreeMem(Controls[i], SizeOf(controls[i]^));

2) Ерекше тәсіл – деструкторды жариялап, Dispose-ды шақырудың кеңейтілген синтаксисін пайдалануға болады, яғни

Dispose(Controls[i], Done);

мұнда Done – деструктор-тәсілдің атауы.

«Baribar.kz-тің» Telegram-каналына жазыламыз!