Pagalvojimai apie ateitį: geresni konstruktoriai
Nors šiuo metu dar gal ir nežinote kas yra paveldimumas, bet kažkada
ateityje matyt teks su tuo susidurti. Tam, kad
paveldimumas veiktų kaip turėtų, reikia naudoti bless()
su
dviem argumentais. Antruoju argumentu yra
perduodama klasė, į kurią bus „palaiminama“.
Tuo pačiu padarysime konstruktorių lankstesnį, kad būtų jį galima
iškviesti tiek kaip klasės, tiek kaip ir objekto
metodą. T.y. kad būtų galima rašyti:
$as = Asmuo->naujas(); $ji = $as->naujas();
Viskas ką mums reikia padaryti, tai patikrinti ar į konstruktorių
buvo perduota nuoroda (reference) ar ne.
Funkcija buvo iškviesta kaip objekto metodas jeigu buvo
perduota nuoroda – tokiu atveju reikia
sužinoti kas tai per klasė naudojantis funkcija ref()
. Jei
perduota ne nuoroda, o paprasčiausias klasės
pavadinimas, tai juo ir naudojamės (tokiu atveju funkcija iškviesta kaip
klasės metodas).
sub naujas { my $perduota = shift; my $klase = ref($perduota) || $perduota; my $mano = {}; $mano->{VARDAS} = undef; $mano->{AMZIUS} = undef; $mano->{KOLEGOS} = []; bless ($mano, $klase); return $mano; }
Štai ir viskas ką reikia žinoti apie konstruktorius. Jie suteikia
objektams gyvenimą grąžindami nuorodas į supakuotus
nepermatomus daiktus vadinamus objektais. Po to šiuos objektus galima
naudoti iškviečiant jų metodus.
Destruktoriai
viskas kas turi pradžią, turi ir pabaigą. Objekto pradžia yra
konstruktoriaus metodas, o pabaiga –
destruktorius. Destruktorius yra metodas, kuris automatiškai
iškviečiamas tada kai objektas nustoja egzistuoti.
Destruktoriai Perle turi būti pavadinti funkcijos vardu
DESTROY
ir naudojami atlikti švarinimo darbus
(uždaryti atidarytas bylas, soketus, ir panašiai)
Kodėl konstruktoriai gali vadintis kaip nori, o detruktoriai ne? Tai
yra būtina todėl, kad konstruktorius iškviečia
pats programuotojas, o destruktoriai yra iškviečiami automatiškai paties
interpretatoriaus (pe rgarbage
collection mechanizmą). Todėl reikia destruktorių vadinti vardu
DESTROY
tam kad Perlas žinotų ką
iškviesti. Perlas neduoda garantijų kad DESTROY
bus
iškviestas tuoj po objekto sunaikinimo – jis
iškviečiamas kada patogiau pačiam Perlui, todėl destruktoriuje į tai
reikia atsižvelgti.
Kodėl DESTROY
rašomas visomis didžiosiomis raidėmis?
Perlas turi tradiciją vadinti visas funkcijas,
kurios bus iškviečiamos pačio interpretatoriaus, o ne programuotojo
vadinti didžiosiomis raidėmis. Panašiai yra su
BEGIN
, END
, AUTOLOAD
bei visais
metodais priklausančiais tie
mechanizmui (žr. perltie dokumentaciją)
Objektinėse kalbose dažniausiai visai nereikia sukti galvos kada bus
iškviestas destruktorius. Jis iškviečiamas tada
kada reikia. Žemo lygio programavimo kalbose, kuriose nėra automatinio
atminties valdymo niekaip neįmanoma padaryti taip,
kad destruktorius būtų iškviestas automatiškai jį sunaikinus – tam
programuotojas pats turi iškviesti desktruktorių
ir atlaisvinti atmintį ir kitus resursus. Perle, ne taip kaip C++,
objektų destruktoriai retai reikalingi, o jei jie ir
reikalingi tai jie iškviečiami automatiškai. Mūsų klasėje
Asmuo
mums nereikia destruktoriaus, nes Perlas
pats pasirūpina tokiais paprastais dalykais kaip atminties
atlaisvinimas.
Vienintelė situacija, kai Perlo magija gali nesuveikti gali būti
tokia, kai naudojama duomanų struktūra, rodanti į
pati save:
$sitas-gt;{BETKAS} = $sitas;
Tokiu atveju reikia ištrinti tokią nuorodą į save pačiam, jei
nenorite kad programa naudotų vis daugiau atminties
(memory leak). Tiesa, kai programa baigia darbą, visa atmintis
grąžinama, tad kažkada ji bus
atlaisvinta, išskyrus atvejus kai ji niekada nebaigia darbo.
C++ destruktoriai kvieciami automatiskai!
ta prasme C++ vis tiek reik daryt
delete foo
, o perle objektas i6trinamas sutomati6ka kai baigiasi jo bloko galiojimasnote to myself: nerašyti komentarų į savo weblogą prigėrus, nes painiojasi lietuviškos raidės.
Nu nevisi (tiksliau nedaug) objektu kuriami su new =) , o ant steko esantys objektai destruktinami kai iseina is scope`o, taigi destruktorius kvieciamas automatiskai.