Программалау іі» пәні бойынша 050111 «Информатика»


Лекция 14 Виртуаль тәсілдер



бет12/29
Дата14.06.2016
өлшемі2.7 Mb.
#135126
түріПрограмма
1   ...   8   9   10   11   12   13   14   15   ...   29

Лекция 14

Виртуаль тәсілдер.


Жоспар:

1. Тәсілді шақыру ерекшеліктері

2. Паскалдағы кеш байланысу

3. Виртуал тәсілдер

4. Виртуал тәсілдері бар объект экземплярларының жадыдағы көрінісі

Әдебиеттер:


1.А.Г.Гольцев «Объектно-ориентированное программирование и его реализация в языке Паскаль», Москва-2005

2. В.В.Фараонов «Турбо Паскаль 7.0», Москва-2001

3. Электронный учебник: «Введение в объектно-ориентированное программирование», 2006
1. Тәсілді шақыру ерекшеліктері

Жоғарыда қарастырылған мысалда (жанып-өшетін объект) Blink тәсілін (белгілі-бір уақыт аралығында жану) қолдану тілегі туындауы мүмкін. Әрине бұл тәсіл белгілі-бір уақыт аралығы өткен сайын барлық үш класс үшін де Show мен Hide тәсілдерін шақырып отыру керек. Бірақ әрқайсы класс үшін өзінің Show мен Hide-ы шақырылады.



Tblinker класына осы тәсілді ендірейік

procedure TBlinker.Blink;

begin

while not keypressed do begin

self.Show;

delay(100);

self.Hide;

delay(100);

end;

end;
Айталық, бұл тәсіл барлық класстарға мұраға берілсін. Көрсеткіш жарияланып, ұрпақ-класс экземпляры құрылған болсын:

var ColorBlinker:PColorBlinker;

.........................

new(ColorBlinker);

ColorBlinker^.Init(10,10,10);

ColorBlinker^.Blink;
Не жанып-өшеді? Ақ нүкте? Неліктен?

Компилятор қайсы тәсілді шақыруды осы тәсіл қайсы объектке қатысты шақырылып тұрған болса сол объект экземплярының типі туралы мәліметке сүйеніп шешеді. ColorBlinker^ -дің типі – TcolorBlinker, демек Blink тәсілі осы класстан шақырылып отыр. Бұл тәсілді мұраға алған, сондықтан өзініңкі жоқ. Барлық үш класс үшін де тәсіл - сол біреу ғана.

Өзіңізді компилятордың орнына қойыңыз да Blink тәсілін компиляция жасап көріңіз. Blink тәсілінің ішінде Show және Hide шақырулары тұр. Олар Self-ке қатысты шақырылып тұр. Self-ң типі қандай? Tblinker, өйткені тәсіл осы класста ендірілген. Демек Blink тәсілінің кодында дәл TBlinker.Show және TBlinker.Hide тәсілдерінің шақырулары тұр. Сондықтан да нүкте ақ түсті.

2. Паскалдағы кеш байланысу

Бұл жағдайдан былай шығуға болады: Blink тәсілін сол бір ғана бастапқы кодымен үш класстың әрбіріне көшіріп шығу керек. Бұл ыңғайлы болмайды (және кейбір мүмкіндіктер жоғалуы мүмкін).

Басқа бір жолы – бұл тәсілді кеш байланысу механизмімен қолдану. Сонда Show және Hide тәсілдері қайда орналасқандығын оның көрсеткіші қалай сипаттталғандығына қарап анықтауға емес(көрсеткіш өзінің классынан басқа кез-келген ұрпақ-класстың экземплярын көрсетіп тұруы мүмкін, ал ұрпақ класстың тәсілдері өзініңкі болуы мүмкін), тікелей объекттің өзінің эземплярынан алуға болады.

Тәсіл кеш байланысу механизмін қолданып шақырылуы үшін, ол тәсіл виртуал не динамикалық деп жариялануы керек.

Компилятор программада виртуал не диамикалық тәсілді кездестірген уақыттта мағынасы мынадай болатын ерекше кодты генерациялайды:

1) Тәсіл қайсы объекттің экземплярына қатысты шақырылып тұрса, сол объекттің экземплярынан виртуалді тәсілдер адресі жазылған талица көрсеткішін алу. Бұл көрсеткіш осы экземпляр тиісті болған класс үшін бар болады.

2) Таблицадан керекті тәсілдің адресін іздеп табу(динамикалық және виртуал тәсілдер үшін іздеу жолы әртүрлі)

3) Тәсілдің айқын параметрлерін және шақырылатын экземплярдың көрсеткіші Self-ті алдын ала стекке орналастырып алып, көрсетілген адрес бойынша шақыру жасау.

Осылайша, компилятор шақырылатын тәсілдің адресін объектті білдіретін айнымалы(не оның көрсеткіші) типіне қарап емес, объект денесіндегі мәліметтер негізінде анықтайды.

Жалпы барлық тәсілдер осылай шақырылуы керек. Алайда, виртуал, әсіресе динамикалық тәсілді шақыру қарапайым статикалық тәсілді шақыруға қарағанда ұзақ уақыт талап етеді. Бұл таблицадан тәсіл адресін іздеу үшін қосымша әрекеттер орындалатындығынан. Сондықтан, программа тиімділігін жоғарылату үшін кеш байланысу механизмін талап етпейтін тәсілдерді статикалық деп жариялап қойған дұрыс.

Әдетте, виртуалды(динамикалық) сияқты, мұрагерлік тізбегі үшін ортақ боп табылатын, бірақ ұрпақ-класстарда әр-түрлі реализацияны талап ететін хабарламаларға реакция (жауап) жасайтын тәсілдерді жариялап қойған дұрыс.

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

(Другими словами – если вы собираетесь вызывать этот метод у экземпляра класса потомка, считая, что он – разновидность предка, поэтому должен как-то понимать этот запрос.)

Егер берілген класстың ұрпақтары жоқ болатын болса, онда оның тәсілдерін виртуалды ретінде жариялаудың маңызы жоқ.

Әрекетті орындайтын классты дәл анық білген жағдайда немесе ұрпақ-класста қайта анықталмайтын жағдайда да тәсілдерді виртуал етудің қажеті жоқ. Дербес жағдайда, бұл – класс экземпляры құрылғаннан кейін артынша шақыруға арналған инициализация тәсілдері боп табылады. Бұл кезде оның әрекетінің мәнін «аталық-класстың мына әртүрлілігін инициализация жасау» деп емес, «мына объектті мұрагерлік тізбегіне қатысы жоқ, дәл өзінің классының экземпляры ретінде инициализация жасау» деп ұғыну керек.

Жоғарыда қарастырған өшіп-жанатын объект және Blink әрекеті мысалында Show және Hide тәсілдері үшін мұрагерліктің барлық тізбегінде кеш байланысу механизмін қолданудың мәні бар болар еді. Blink тәсілінің өзін аталық-класста ғана жариялап қоюға болар еді, дәл осы Blink тәсілін кеш байланысумен шақыру талап етілмейді.

procedure TBlinker.Blink;

begin

while not keypressed do begin

self.Show; delay(100);

self.Hide; delay(100);

end;

end;
Self.Show және Self.Hide-ты шақыру кезінде ол Self көрсеткішін алып, ондағы адрес бойынша виртуал тәсілдердің адресі жазылған таблицаны тауып, сол арқылы Show немесе Hide-ты шақырар еді. Маңыздысы мынада, егер осы Blink тәсілі TBlinker классы ұрпағының экземплярына қатысты шақырылса, онда Self ұрпақ- экземплярды көрсетіп тұрар еді, демек таблица да ұрпақ- экземплярыдыңкі болар еді, және TBlinker классының тәсілдері емес, керекті класстың тәсілдері шақырылар еді.

3. Виртуал тәсілдер

Виртуал тәсілді сипаттаудың синтаксисі. Объект интерфейсінде тәсіл virtual кілттік сөзі арқылы сипатталады.

type TBlinker=object

...


procedure Show; virtual;

...


end;
Тәсіл реализациясы кәдуілгідей сипатталады.

Барлық ұрпақ-класстарда виртуал тәсіл егер ол қайта анықталатын болса, дәл аталықтағы параметрлер жиынына ие болу керек.


4. Виртуал тәсілдері бар объект экземплярларының жадыдағы көрінісі

1) Егер класста виртуал тәсілдер бар болатын болса(өзініңкі немесе мұраға алынған), онда сол виртуал тәсілдердің адрестері VMT –да (virtual method table, виртуал тәсілдер таблицасында)сақталады.

2) VMT жалпы класс үшін біреу.

3) Мұндай класстың әрбір экземпляры нақты жарияланған өрістерден бөлек қосымша екібайттық өріске ие. Бұл өрісте VMT жылжуы(смещение) сақталады(оның сегменті-берілгендер сегменті).


4) Бұл өріс экземпляр құрылу барысында автоматты түрде инициализация жасалынбайды. Инициализация жасалынуы үшін программист конструктор деп аталатын ерекше тәсілді нақты түрде шақыруы керек.

5) Бұл өрістің орналасқан орны(оның экземпляр басына қатысты жылжуы, смещение) – мұрагерліктің барлық тізбегінде бірдей. Егер қайсыбір класстың мұрагерлік тізбегінде ол бірінші рет кездесіп тұрған болса – онда осы класстың өзінің және мұраға алынған барлық өрістерінен кейін тұрады.

6) Бұл өрісті тікелей пайдалануға(прямой доступ) болмайды, өйткені жадыдағы объекттердің көрінісі компилятордың бір версиясынан келесі версиясына өзгеріп отырады.

7) Классы не класс экземпляры көрсетіліп, шақырылған TypeOf функциясы класстың VMT-сына толық көрсеткішті қайтарады. Егер параметр ретінде экземпляр объекті көрсетілсе, онда VMT адресі дәл осы VMT өрісінен алынады.

Келесі суреттерде класс экземплярларының VMT-мен байланысы және мұрагерлік қатынастағы экземплярларда VMT-ға жасалынған сілтемелер өрісінің орналасуы бейнеленген.







Достарыңызбен бөлісу:
1   ...   8   9   10   11   12   13   14   15   ...   29




©dereksiz.org 2024
әкімшілігінің қараңыз

    Басты бет