Жоспар:
1. Конструктор
2. Мұраға алынған(inherited) конструктордың шақырылуы
Әдебиеттер:
1.А.Г.Гольцев «Объектно-ориентированное программирование и его реализация в языке Паскаль», Москва-2005
2. В.В.Фараонов «Турбо Паскаль 7.0», Москва-2001
3. Электронный учебник: «Введение в объектно-ориентированное программирование», 2006
1. Конструктор
- бұл экземпляр-VMT байланысын(объект экземплярындағы VMT-ға көрсеткішті) инициализация жасауға арналған ерекше тәсіл. Конструкторды жариялауда procedure сөзінің орнына constructor қызметші сөзі жазылады. Реализациясын жариялауда да constructor сөзі қолданылады.
Класс үшін VMT қай уақытта құрылады? Класста не оның аталық-класстарында мына шарттардың ең кемінде біреуі орындалған жағдайда:
1) Ең кемінде бір тәсіл виртуал не динамикалық деп жарияланған.
2) Ең кемінде бір тәсіл конструктор ретінде жарияланған.
3) Ең кемінде бір тәсіл деструктор ретінде деп жарияланған.
Конструктор не істейді? Ол объект экземплярында VMT көрсеткішінің өрісін инициализация жасайды; оған құрылып жатқан объект қай классқа тиісті болса сол класстың VMT жылжуын жазады.
Бұдан бөлек, конструктор денесінде әдетте экземплярды инициализация жасау әрекеттерін орналастырады. VMT өрісі конструктор денесі инициализация жасалынбай тұрып, инициализация жасалынады.
Конструктор виртуал бола алмайды, себебі, жоғарыда айтылған виртуал тәсілдерді шақыру әдісі бойынша VMT-ны пайдалану(обращение к VMT)– бұл экземплярда тұрып VMT-ға сілтеме жасау дегені, ал дәл осы сілтемені конструктор инициализация жасайды.
Конструкторды шақыруға дейін VMT адресі экземпляр өрісіне жазылмаған болады, сондықтан, виртуал тәсілді шақыру қателікке алып келеді.
2. Мұраға алынған(inherited) конструктор қалай шақырылады?
Ол VMT өрісіне аталық-класс VMT-ң сілтемесін жазып қою керек еді ғой. Жауап мынадай:
1) егер конструктор объект экземплярын көрсетумен(соның ішінде, басқа бір тәсілдің ішінде Self-ке қатысты немесе Self-ті көрсетпей-ақ) шақырылатын болса, онда ол объект экземплярының VMT өрісін инициализация жасағанда объект экземплярының адресі жазылған айнымалының қандай типте жарияланғандығын басшылыққа алады.
2) Егер конструктор мұраға алынған сияқты шақырылатын болса(басқа бір тәсілдің ішінен inherited қызметші сөзі не аталық-класс атауы көрсетіліп), онда ол VMT өрісінинициализация жасамайды, қарапайым инициализация тәсілі секілді жұмыс істейді(дәлірегі, ол логикалық мән қайтарады, бұл туралы кейінірек тоқталамыз).
Бірінші ережеден келіп шығатын салдар. Егер мұраға алынған және қайта анықталмаған конструктор ұрпақ экземплярына қатысты шақырылса, онда VMT өрісі әрекетті орындаушы-объектті білдіретін айнымалы типіне сәйкес инициализация жасалынады, яғни оған ұрпақ VMT-ң көрсеткіші коррект жазылатын болады.
VMT көрсеткішін инициализациялау кодын шақыру компилятор арқылы конструкторды шақыру кезінде қосымша өз-өзінен қойылады, яғни ол конструктор кодының бір бөлігі боп табылмайды. Дәл осыған байланысты мұраға алынған конструктор (аталықтың экземплярына қатысты шақырылып тұрып) VMT көрсеткішін аталықтың экземплярында дұрыс инициализация жасайды.
Рекомендация. Программаның қауіпті болу мүмкін аймақтарын тудырмау үшін басқа тәсіл конструкторларын шақырмаған дұрыс. Алайда, берілген класста мұраға алынған және қайта анықталған конструкторды осы конструктордың жаңа реализациясынан шақыруға болады.
Ішкі класста қайтаанықталу кезінде мұраға алынған конструктор конструктордың жаңа реализациясы денесінде әдетте, ең басында шақырылады.
3. Конструкторды корректсіз қолданудың мысалы.
type
TA = object
.........
constructor init;
procedure Initialization;
.........
end;
PA = ^TA;
TB = object(TA)
.........
end;
PB = ^TB;
procedure Initialization;
begin
Init; {конструкторды шақыру, Self.Init – рекомендацияға жат!}
...........
end;
................
var B:PB;
................
new(B);
B^.Init; {мұраға алынған конструктор шақырылып тұр, бұлай етуге болады }
B^.Initialization; {VMT-ң көрсеткіші бұзылады!}
Келтіріліген мысалда TA классы және оның мұрагері TB жарияланған. TA классында конструктор жарияланған және осы конструктордың тәсілін өз ішіне алатын тәсіл жарияланған(бұлай етуге кеңес бермейміз). TB классында осы конструктор мен тәсіл мұраға алынған. B^.Init шақыруы мұраға алынған конструкторды дұрыс (коррект)шақыруға әкеледі. Бұған дейін компилятор B^ объектінің VMT өрісін инициализациялау кодын генерациялап қояды. Өйткені, адрестелетін В мәні TB типіне ие. Келесі B^.Initialization шақыруы мұраға алынған тәсілді шақыруға әкеледі, ал, оның ішінде конструктор қайтадан шақырылады. Осы тәсілдің ішінде конструкторды шақыру Self-ке қатысты орындалады, ал бұл Self осы тәсілдің контексінде TA типіне ие. Сондықтан, нәтижеде, Self ретінде берілген B^ объекті, қайта инициализацияланатын болады және оның VMT өрісіне ТА классының VMT адресі жазылады, ал бұл корректсіз(дұрыс емес).
Лекция 16 Delphi программалау ортасы
Жоспар:
1. Кіріспе
2. Delphi-ді іске қосу. Delphi ортасы
3. Проект. Форма.Қасиеттер. Қасиеттер терезесі
4. Оқиғалар
Пайдаланылған әдебиеттер:
Негізгі:
-
О. Камардинов. Х.Жантелі, DELPHI 5 – 6 , Оқу құралы. Шымкент, 2002
-
И.Баженова, Дельфи 7, Кудиц-Образ, М.-2003
-
В.Попов, Паскаль и Дельфи, Питер-2003
-
В.Фараонов, Delphi 6, учебный курс, М.-2001
-
Электронный учебник, Иллюстрированный самоучитель по Дельфи 7 для начинающих
Қосымша:
-
А.Полянский. Среда программирования Delphi 5-6 Справочное пособие. М.,2001
-
С.Бобровский. Delphi 5. Учебный курс. М.2001
-
Н.Культин. Delphi 6. Программирование на Object Pascal. БХБ-Петербург, 2001
Достарыңызбен бөлісу: |