s e b e s s é g e k n é l a rakéta hatásfoka kicsiny, ezért nem előnyös a rakéta autókban és más, viszonylag lassú mozgásoknál. Nagy s e b e s s é g e k n é l is c s ö k k e n a rakéták energetikai hatásfoka, a z o n b a n e z a körülmény n e m szól a rakéták alkalmazása ellen, amíg nincs más a testek nagy sebességekre való felgyorsítására.
A kozmikus s e b s s é g e k elérése érdekében az űrhajókat függőleges irányban indítják fel ( a légkörben való minél előbbi túljutás miatt), majd a s e b e s s é g irányát k ö z e l 90°-kal megváltoztatják.
Nagy sebességek üzemanyag spórlással úgy érhetők el, h o g y t ö b b l é p c s ő s rakétákat használnak; a lépcsők tartályai az üzemanyag elégetése után fokoza
tosan leválnak, így az üres tartályok gyorsítására üzemanyag már n e m fordítódik.
Végül megemlítjük két „titánnak" a nevét, akik az űrhajózás gyakorlati megvalósításaiban játszottak kimagasló szerepet: Wernher v o n Braun-t, aki t ö b b e k között megtervezte a gigászi Szaturnusz V. típusú rakétát é s Szergej Pavlovics Koroliovot, az e l s ő Szputnyik a Föld körüli pályára állítására használt rakéta főkonstruktőrét.
F e r e n c z i J á n o s Nagybánya
Szerk. megj.: A modern rakétatechnika megalapozója, az ameriaki J e t Propul- sion rakéta hajtóművek kutatólaboratóriumának létrehozója és vezetője, a budapesti születésű Kármán T ó d o r ( 1 8 8 1 - 1 9 6 3 ) , az ő nevét is é r d e m e s m e g e m lítenünk.
Borland Delphi - az Object P a s c a l nyelv
A Delphi fejlesztői környezet színfalai mögött az Object Pascal nyelv áll. A nyelv számos olyan újdonságot tartalmaz, amelyek biztosítják, h o g y a Pascal nyelv alkalmas legyen Windows-alkalmazások fejlesztésére illetve olyan m e g - oldásokkal szolgálnak, amelyek hatékonyabb programkódhoz vezetnek. A k ö v e t k e z ő k b e n megpróbáljuk összefoglalni mindazon változásokat, újdon- ságokat, amelyeket az Object Pascal nyelv hozott.
Új típusok
A W i n d o w s fejlesztői környezet filozófiája nagyméretben befolyásolta a típusok kialakítását. Az egész típusok új e l e m e k k e l bővültek, lehetővé téve, h o g y a fejlesztői környezet 1 6 - vagy 3 2 bites mivoltát kihasználják. Megjelenik a Cardinal típus, amelynek mérete függ a rendszertől ( 2 6 - vagy 32 bit). A logikai típus pedig a rendszer igényeinek megfelelően többféle m é r e t b e n áll ren
delkezésünkre: Boolean (false..true, 8 bites), ByteBool (false..true, 8 bites), WordBool (false..true, 16 bites), L o n g B o o l ( f a l s e . . t r u e , 3 2 bites).
V á l t o z á s o k a p a r a m é t e r á t a d á s b a n
Az Object Pascal nyelv paraméterátadása is kibővült. Számos olyan új le- hetőséget tartalmaz, amely hatékonyabb kód fordításához vezetnek.
A Pascal nyelvben megszokott kimeneti (var), illetve b e m e n e t i paraméterek mellett lehetőség adódott konstans (const) paraméter átadásra is. A konstans paraméter értéke az eljáráson vagy a függvényen belül n e m változtatható meg.
A konstans paraméterekről a fordító nem készít lokális másolatot a v e r e m b e n , emiatt sokkal hatékonyabb k ó d j ö n létre tömb, rekord, string paraméterek használata esetén. A konstans formális paraméter helyén tetszőleges aktuális
F i r k a 1 9 9 7 - 9 8 / 2 5 5
paraméter (kifejezés, változó, érték) megadható. A v a r paraméterekhez h a s o n - lóan használható típus nélküli paraméter deklarálására is. E b b e n az e s e t b e n a z o n b a n az aktuális paraméter csak változó lehet.
procedure ConstPar(const a,b: integer; var c: integer);
begin c : = a + b;
a : = b ; { hibás utasítás}
end;
Az Object Pascal nyelv a nyitott (open) paraméterek használatát is támogatja.
Ilyen paraméterek segítségével az eljárások vagy függvények tetszőleges méretű t ö m b b e l illetve stringgel hívhatók meg.
Ha a string típus helyett OpenString típust adunk meg, a k k o r az aktuális paraméter tetszőleges string típusú változó lehet. Az eljáráson vagy a függvényen belül a formális paraméter hossza mindig meg fog egyezni az aktuális string paraméter hosszával.
A nyitott tömb paraméterek lehetőséget biztosítanak arra, h o g y olyan függ- vényeket vagy eljárásokat írjunk, melyek hívása nem függ a paramétertömb méretétől. E h h e z a formális paramétertömböt az array of ElemTipus deklarációval kell, h o g y bevezessük. Az eljáráson vagy a függvényen belül úgy használhatjuk a nyitott tömböt, mintha array[0..n-l] of ElemTipus típusú l e n n e , a h o l n az aktuális paraméterként átadott t ö m b e l e m e i n e k a száma. Az alprogramon belül a High függvénnyel kérdezhetjük le a nyitott t ö m b paraméter utolsó e l e m é n e k az indexét. A Low függvény 0 értéket ad vissza é s a SizeOf az aktuális paramétertömb b y t e o k b a n kifejezett méretével tér vissza,
function Media (a: array of integer) : real;
var
s: longint;
i: integer;
begin s := 0;
for i := 0 to High (a) do s := s + a[i];
Media := s / (High(a) + 1 ) ; end;
Az Object Pascal érdekes lehetősége, hogy ha nyitott t ö m b formális paraméter- rel deklaráltunk e g y eljárást vagy e g y függvényt, akkor az alprogram olyan konstans t ö m b b e l is meghívható, amelynek az elemeit szögletes zárójel k ö z é soroljuk fel.
writeln (Media ([10,9,8,10,9,9,9,10,8,7,10]));
megadhatunk típus nélküli nyitott t ö m b paramétereket is az array of const deklarációval. A Delphi ezt úgy oldja meg, hogy a System unitban e g y TVarRec típust és hozzá tartozó konstansokat deklarál:
const
vtInteger = 0 ; vtBoolean = 1 ; vtChar = 2 ; vtExtended = 3 ; vtString = 4 ; vtPointer = 5 ; vtPChar = 6 ; vtObject = 7 ; vtClass = 8 ; type
TVarRec = record case Integer of
vtInteger: (VInteger: Longint;VType: Byte);
vtBoolean: (VBoolean: Boolean);
vtChar: (VChar: Char);
vtExtended: (VExtended: PExtended);
vtString: (VString: PString);
vtPointer: (VPointer: Pointer);
vtPChar: (VPChar: PChar);
vtObject: (VObject: TObject);
vtClass: (VClass: TClass);
end;
Az array of const deklaráció tulajdonképpen az array of TVar Rec deklarációval a z o n o s . A deklarált vtXXX konstansok segítségével a t ö m b minden e l e m é n e k a típusa lekérdezhető. A k ö v e t k e z ő függvény e g y tetszőleges t ö m b elemeit stringgé konkatenálja:
function MakeString (a: array of const) : string;
var
i : integer;
s : string;
begin s : ='';
for i := 0 to High(a) do with a[i] do
case VType of
vtInteger: s := s + IntToStr(VInteger);
vtBoolean: case VBoolean of false: s := s + 'false';
true: s := s + 'true';
end;
vtChar: s := s + VChar;
vtExtended: s := s + FloatToStr(VExtendedˆ);
vtString: s := s + VStringˆ;
end;
MakeString := s;
end;
Ö s s z e t e t t típusú f ü g g v é n y é r t é k e k
A P a s c a l b a n megszokott típusok mellett az O b j e c t Pascal függvények összetett típusú (rekord, tömb, halmaz, stb.) értékekket is szolgáltathatnak vissza. T o v á b b r a s e m használhatók azonban az o b j e c t és az állománytípusok.
Az Assigned f ü g g v é n y
Az előredefiniált Delphi függvények nagy része pointerekkel v é g e z műveletet és nil értékkel tér vissza hiba esetén. Ezért a visszaadott értéket mindig tesztelni kell. Az if p = nil tesztet az Object Pascal hatékonyabbá és olvashatóbbá teszi az if not Assigned(p) teszt segítségével. Az Assigned függvény deklarációja tehát:
function Assigned(var p): boolean;.
A n u l l t e r m i n á l s t r i n g e k h a s z n á l a t a
Az Object Pascal nyelv lehetőséget nyújt a C-ben megszokott null-terminál stringek használatára is. Ezeket a PChar = ˆChar, vagy az array[0..n] of char, típusokkal lehet deklarálni. A stringeket e g y #0 karakter zárja le. A null-terminál stringeket e x t e n d e d (kibővített) szintaxis mellett lehet használni. Ezért a program a {$X+} direktívát kell, hogy tartalmazza. A null-terminál stringek használatát h a t é k o n y SysUtils unitbeli assembly rutinok segítik e l ő . Ilyen függvények pl.:
function StrLen (Str: PChar) : word; egy null-terminál string hosszát adja meg, function StrUpper (Str: PChar: ) : Pchar; nagybetűssé alakít egy
stringet,
F i r k a 1 9 9 7 - 9 8 / 2 5 7
function StrLower (Str: PChar) : Pchar; kisbetűssé alakít egy stringet,
function StrPas (Str: PChar) : string; null-terminál stringet Pascal típusúvá alakít, function StrComp (s1, s2 : PChar) : integer; összehasonlít két
stringet, stb.
O b j e k t u m o k a z O b j e c t P a s c a l n y e l v b e n
Ahhoz, h o g y tervezési időben is hozzá tudjunk férni az o b j e k t u m o k h o z , m e g f e l e l ő e n ki kellett bővíteni a Delphi objektumorientált részét. A régi progra- m o k k a l való kompatibilitás miatt természetesen megmaradt és ugyanúgy használ- ható az object típus, de az új fogalomnak megfelelő fejlesztés csak a class típus és így az új alapelem, a k o m p o n e n s bevezetésével valósulhatott meg.
Az Object Pascalban bevezetett class típus felépítésében és használatábnan is hasonlít az object típusra. Lényeges különbség az, hogy a c l a s s típus példányai dinamikusan j ö n n e k létre és minden új típusnak van elődje, a TObject típus.
Az a d a t m e z ő k és a metódusok mellett a class típusok jellemzőket (property) is tartalmazhatnak. A jellemző olyan névvel ellátott attribútuma a típusnak, amelyre csak az olvasás és/vagy az írás műveletét definiáljuk. E b b e n a k o n t e x - tusban elmondhatjuk tehát, h o g y a jellemző definíciója az osztályban e g y nevet, e g y típust és műveleteket tartalmaz. A jellemzők képezik tulajdonképpen a Delphi által támogatott komponens-orientált fejlesztés alapját. Ezek a jellemzők mind tervezési, mind futási időben elérhetők,
property prop: integer read GetProp write SetProp;
ha a j e l l e m z ő kifejezésben szerepel, akkor annak értékét a read direktíva után megadott adat vagy metódus szolgáltatja. Ha a jellemző értékadásban szerepel, a k k o r a megadott érték a write direktíva után megadott adatnak vagy metódusnak adódik át.
A jellemzők lehetséges típusai:
• egyszerű típus (numerikus, karakter, string)
• felsorolt típus
• halmaz
• objektum (a TPersistent típusból származtatott)
• t ö m b
A n e m t ö m b j e l l e m z ő definíciója más, opcionális tárolási direktívákat (stored, default, nodefault) is tartalmazhat a read és a write után.
property prop: integer read GetProp write SetProp stored true default10;
A stored direktívával azt jelzi a rendszer, hogy a jellemző értéke állományban írodott-e vagy sem. Így a stored direktíva lehetséges értékei: true vagy false, e g y logikai típusú adat, e g y logikai típusú értékkel visszatérő függvény ( m e t ó d u s ) . A default direktívával megadhatjuk a jellemző alapértelmezett értékét, illetve h a nincs ilyen, a k k o r ezt a nodefault-tal jelölhetjük.
Az a d a t r e j t é s új l e h e t ő s é g e i
Az o b j e k t u m Pascalban megszokott b e l s ő (private) és kívülről is e l é r h e t ő (public) adatai, metódusai é s jellemzői mellett az Object Pascal még két adatrejtési módot definiál: a protected és a published elérhetőséget.
A protected (védett) elérhetőségű részei az objektumnak p r i v a t e e l é r é s ű a külvilág számára, ha azonban saját osztályt származtatunk a védett e l e m e k k e l r e n d e l k e z ő típusból, akkor e z e k public elérésűvé válnak. A published direktíva ugyanúgy viselkedik, mint a public, azzal a különbséggel, hogy e z e k h e z az
a d a t m e z ő k h ö z , jellemzőkhöz a rendszer futásidejű típusinformációkat kapcsol.
A Delphi környezetben az Object I n s p e c t o r n a k van szüksége ilyen információkra.
O b j e k t u m p é l d á n y o k
A class típus valójában e g y mutatótípus, amellyel létrehozott változó az objektumpéldányra fog mutatni. Az objektumpéldány számára memóriaterületet konstruktorral foglalunk, míg a terület felszabadításáról a destruktor g o n d o s - kodik. A class típus objektumainak a konstruktora a Create, destruktora pedig a Destroy. Ezekre az objektumokra n e használjuk a new és a dispose függvényeket, s e m a ˆ referenciát.
O b j e k t u m o k h i e r a r c h i á j a
Az Object Pascal megtartotta a Pascal nyelv egyszeres öröklődését, tehát a class típusoknak is egyetlen közvetlen ősük lehet. Az előredefiniált TObject osztály minden osztály közös ő s e . Ha a típusdeklarációban elhagyjuk az ő s osztály megadását, akkor automatikusan a TObject osztálytól fog származni az új típus. A TObjectet a System unit deklarálja:
type
TObject = class;
TClass = class of TObject;
TObject = class
constructor Create;
destructor Destroy; virtual;
procedure Free;
class function Newlnstance: TObject; virtual;
procedure FreeInstance; virtual;
class procedure InitInstance (Instance: Pointer) : TObject;
function ClassType: TClass;
class function ClassName: string;
class function ClassParent: TClass;
class function ClassInfo: Pointer;
class function InstanceSize: Word;
class function InheritsForm (AClass: TClass) : Boolean;
procedure DefaultHandler (var Message) ; virtual;
procedure Dispatch (var Message);
class function MethodAddress (const Name: string) : Pointer;
class function MethodName (Address : Pointer) : string;
function FieldAddress (const Name: string) : Pointer;
end;
Az ö r ö k l ő d é s során, a közvetlen ő s osztály metódusainak elérése e g y s z e r ű b b é t e h e t ő az inherited direktíva felhasználásával.
Az Object Pascalban a polimorfizmus fogalma is kibővül. Most e z virtuális (virtual) é s dinamikus (dynamic) m e t ó d u s o k o n keresztül valósul meg. A konst- ruktoron kívül tetszőleges metódus virtuálissá t e h e t ő a virtual, illetve di- namikussá t e h e t ő a dynamic direktíva megadásával. Valamely m e d ó d u s a hierarchia tetszőleges pontján virtuálissá vagy dinamikussá tehető, a z o n b a n a származtatott osztályoknál, ha ezeket a metódusokat újradefiniáljuk, az override direktívát kell, h o g y használjuk. Pascal nyelvből tudjuk, hogy virtuális metódusok használatakor a fordítóprogram Virtuális Metódus Táblának (VMT) nevezett i n f o r m á c i ó s táblázatot készít, az osztályhoz k a p c s o l ó d ó a n . A dinamikus m e t ó d u s o k hívása úgy valósul meg, hogy a dinamikus metódusok adattáblázatai láncot alkotva, csak az adott osztályban definiált dinamikus metódusokról tárolnak információt. A meghívandó dinamikus metódus belépési címét e g y rendszerrutin keresi m e g a láncban.
F i r k a 1 9 9 7 - 9 8 / 2 5 9
A b s z t r a k t m e t ó d u s o k
A hierarchiák t ö b b s é g e olyan típusokból (alaposztályokból) indul ki, a m e l y - n e k virtuális, dinamikus metódusai csak arra szolgálnak, h o g y teljessé tegyék a típus deklarációját. Ezek ún. absztrakt metódusokat tartalmaznak, a m e l y e k az alaposztályban c s a k névlegesen vannak jelen, a származtatott osztályokban pedig m i n d e n k é p p e n újra kell őket definiálnunk. Egy metódus absztrakttá az abstract direktívával tehető:
procedure proc; virtual; abstract;
procedure proc; dynamic; abstract;
O s z t á l y o p e r á t o r o k
Az Object Pascal nyelv két olyan operátort definiál, a m e l y e k n e k operandusai osztály- illetve objektumhivatkozások. Az is operátort dinamikus típusellenőr- zésre használjuk. Segítségével megtudhatjuk, hogy e g y objektum az adott osztályhoz tartozik-e vagy sem:
object1 is ClassType
Az a s operátort típuskonverzió végrehajtására használjuk:
object1 as ClassType
O s z t á l y m e t ó d u s o k
Az Object Pascal nyelv lehetőséget biztosít olyan metódusok létrehozására is, a m e l y e k az objektumpéldány helyett magán az osztályon fejtik ki hatásukat. E z e k az osztálymetódusok (class methods). Ilyen metódusból természetesen s e m az adatokat, s e m a jellemzőket nem érhetjük el, hiszen ezek c s a k az o b j e k t u m példányaiban léteznek. Egy medódust osztálymetódussá tudunk tenni úgy, h o g y deklarációját a class direktívával vezetjük be:
type
TMyObject = class
class function GetName: string;
end;
class function TMyObject.GetName;
begin
GetName := 'TMyObject';
end;
begin
writeln(TMyObject.GetName);
end.
Ü z e n e t k e z e l é s
A W i n d o w s - f i l o z ó f i a alapja az üzenetkezelés. A Delphi ü z e n e t k e z e l ő - m e t ó d u s o k lehetővé teszik, hogy mi fogadjunk és megválaszoljunk dinamikusan továbbított üzeneteket. Egy ilyen metódust a message direktívával kell deklarálni.
Az ü z e n e t e k azonítására és kezelésére a Windows rendelkezésünkre bocsájtja a WM_XXX konstansokat:
type
TInputLine = class(TEdit)
procedure WmKeyUp(var Message); message WM_KEYUP;
end;
A W i n d o w s az üzeneteket továbítja, szórja. Üzenetet küldhetünk az objektu- m o k Dispatch metódusával:
procedure TObject.Dispatch (var Message);
K i v é t e l e k k e z e l é s e
A kivételek ( e x c e p t i o n ) olyan hibás e s e m é n y e k , amelyek megszakítják az alkalmazás szabályszerű futását. Ilyenkor a vezérlés a kivételkezelőnek adódik át. Az Object Pascal nyelv számos olyan eszközt tartalmaz, a m e l y e k lehetővé teszik a kivételek, hibás e s e m é n y e k megkülönböztetését, kezelését. A kivétel- k e z e l é s h e z a Delphi saját objektumhierarchiát deklarál a SysUtils unitban. Ha ezt a unitot használjuk, a futás alatti (run-time) hibák automatikusan k i v é t e l e k k é alakulnak. Így olyan hibákat is ki lehet védni, mint például a memória túlcsor- dulás, általános védelmi hiba stb.
Az Object Pascalban a kivétel egyszerűen e g y osztályként (class) van d e k - larálva. Az új kivételeket az Exception osztályból kell származtatni.
type
EMathError = class(Exception);
Kivételeket a r a i s e utasítás segítségével válthatunk ki:
raise [objektumpéldány] [at cím]];
A k ö v e t k e z ő eljárás ellenőrzi, hogy a beolvasott szám a [0..255] intervallumban van-e, ha nincs, a k k o r e g y kivételt vált ki:
procedure TForm1.ButtonlClick(Sender: TObject);
begin
with Edit1 do
if (StrToInt(Text) < 0) or (StrToInt(Text) > 255) then raise ERangeError.CreateFmt (' %dnincs a [0. .255]
intervallumban!' ,[StrToInt(Text)]);
end;
Megfigyelhetjük, h o g y a mise számára az objektumpéldányt közvetlenül az argumentumban hoztuk létre az ERangeError kivételosztály CreateFmt kontsruk- torával. Fontos megjegyezni azt, hogy miután a kivételkezelés megtörtént, az objektumpéldány automatikus törlődik, vagyis a Destroy destruktor automati- kusan meghívódik.
A kivételek k e z e l é s e a try...except utasítás segítségével történik:
try
utasítások except
kivételek [ else
kivételek]
end;
A program végrehajtja a try utáni utasításokat, ha valamilyen kivétel l é p fel, a k k o r a vezérlés a h h o z a legbelső kivételkezelőhöz kerül, a m e l y alkalmas az adott osztályú kivételek kezelésére. Ha a blokk nem tartalmaz ilyen kivételkeze- lőt, a k k o r a program futása hibajelzéssel leáll. Ha az utasítás tartalmaz else részt is, a k k o r sikertelen keresés esetén e b b e n a részben leírtak fognak végrehajtódni.
A m e g f e l e l ő kivételkezelő leírása az on...do utasítások segítségével történik.
Ezeket a kivételkezelőket a beírás sorrendjében ellenőrzi a rendszer, on [azonosító:] típus do utasítás;
Az azonosító: nem k ö t e l e z ő rész, ezt az utasítás végrehajtása során a kivételob- jektum azonosítására használhatjuk.
Amikor az eljárás vagy függvény nem kezeli le a b e n n e fellépő kivételt, továbbítani kell ezt az eljárást vagy a függvényt hívó külső programrésznek, vagyis újra e l ő kell idézni a kivételt. A kivételek ismételt e l ő i d é z é s e a raise utasításnak az except részben történő megadásával v é g e z h e t ő el.
F i r k a 1 9 9 7 - 9 8 / 2 6 1
try except
on EOverflow do HandleOverflow;
on EMathError do HandleMathError;
on E: Exception do ErrorDialog(E.Message, E.HelpContext);
raise;
else
HandleOthers;
end;
Ha e g y kódrész valamilyen erőforrást használ, mind normális, mind kivétellel megszakított esetben fell kell szabadítani a lefoglalt erőforrást. Ilyen e s e t e k b e n a try...finally utasítást kell használni:
try
utasítások;
finally utasítások;
end;
A program végrehajtja a try után következő utasításokat, ha valamilyen kivétel lép fel i d ő k ö z b e n , a vezérlés átadódik a finally résznek, ha n e m lép fel kivétel, a k k o r is végrehajtódnak a finally részben leírtak. A finally rész utasításainak végrehajtása után a kivétel, ha volt ilyen, automatikusan ismét fellép, a m e l y n e k a kezelését általában e g y külső try...except utasítás végzi el. Az utasítás feltétlenül szükséges olyan e s e t e k kezelésére, amikor függetlenül a hibás vagy helyes végrehajtástól, bizonyos utasításokat végre kell hajtani. Például e g y állományt a feldolgozása után mindig b e kell zárni, bárhogy is fejeződött b e e z a feldolgozás.
Assign(f,nev);
Reset (f);
try
ProcessFile(f);
finally Close(f);
end;
Ha a try részben Exit, Break vagy Continue eljárást használunk, a k k o r a vezérlés átadódik a finally résznek. Ezek az eljárások használhatóak a kivétel- k e z e l ő k b ő l való kilépésre is, e k k o r a kivétel automatikusan megszűnik.
K o v á c s L e h e l
Kémiatörténeti évfordulók
1997. szeptember-október
410 éve, 1587. o k t ó b e r 2 1 , 22, vagy 2 8 - á n született a németországi L ü b e c k b e n JOACHIM JUNGIUS, a „német Bacon". Az atomelmélet felújításában B o y l e
előfutára volt. A kísérletezés fontosságát hirdette. Kritizálta az alkímiát. Felismerte a l e v e g ő szerepét az é g é s b e n és azt tanította, hogy a réz kiválása rézgálic-oldatból vas hatására n e m elemátalakulás, hanem e g y e n l ő számú atom kicserélődése.
1 6 5 7 - b e n halt meg.