Programozás delphi-ban
4.4. A lekötött források védelme a veszteségtől
Amikor a programozó a fordítást követően kap egy fájlt készen a végrehajtásra, ő őszintén hiszi, hogy a program pontosan úgy működik, ahogy akar. Míg ő a gondos kezében van, általában ez történik. Amikor a program súlyosabb feltételekbe kerül - egy új felhasználónak és egy másik számítógépnek - bármi megtörténhet vele. Az "új tulajdonos" betűket írhat be a számok helyett, kivonhatja a gyökeret egy negatív számból, oszthat nullával és sok más kiütést, gyakran véletlenszerű lépéseket tehet. Különösen ez interaktív (interaktív) alkalmazásokra vonatkozik, és ilyen - a túlnyomó többség. Ebből következik, hogy a programozónak meg kell szerveznie erős védekezését a program életében bekövetkező minden beavatkozás ellen végrehajtásának folyamata során. Ennek módját ebben a fejezetben ismertetjük.
4.1. Hibák és kivételek
Tudnia kell, hogy bármilyen futó alkalmazásban hiba léphet fel. A hibák okai különbözőek. Néhányan szubjektívek és a programozó írástudatlan akciói okozzák. De vannak objektív hibák is, amelyeket a program megtervezése közben nem lehet elkerülni, de működés közben megtalálható. Számos példa van ilyen hibákra: elégtelen szabad memória, nincs fájl a lemezen, az eredeti adatok értékének kimenete a megengedett tartományból stb.
Egy jó programnak meg kell birkóznia a hibáival, és dolgoznia kell anélkül, hogy bármilyen körülmények között felakasztaná és lógna. A hibák kezelése érdekében természetesen megpróbálhatja használni az űrlap struktúráit, ha
A kivételes helyzet (kivétel) a program rendes menetének megszakadása, mivel a későbbi lépések helyes végrehajtása nem lehetséges.
A kivételkezelő mechanizmus a legmegfelelőbb a program-interakcióhoz a szubrutin könyvtárral. A könyvtári rutinok hibákat észlelnek, de a legtöbb esetben nem tudják, hogyan reagáljanak rájuk. A hívó program éppen ellenkezőleg, tudja, mi a teendő hibák esetén, de általában nem tudja, hogyan kell időben felismerni őket. A kivételkezelő mechanizmus miatt a könyvtár és az azt használó program kezelése a hibakezelés alatt történik.
A kivételkezelés mechanizmusa meglehetősen bonyolult végrehajtása, de a programozó számára egyszerű és átlátható. Ennek használatához speciális próbaterveket vezettek be a Delphi nyelvre. kivéve. végén. próbálni. végül. vége és az emelés megállapítása. ebben a fejezetben.
4.2. Kivételosztályok
Kivételes helyzetek a Delphi nyelven osztályok írják le. Minden osztály egy bizonyos típusú kivételnek felel meg. Ha a programban kivétel történik, a megfelelő osztály egy objektumot hoz létre, amely információt szolgáltat a helyzetről a származási helyről a feldolgozási helyre.
A kivételosztályok hierarchiát alkotnak, amelynek gyökere az Exception osztály. Az Exception osztály leírja a kivétel leggyakoribb típusát, és örökösei az ilyen helyzetek meghatározott típusai (4.1. Táblázat). Például az EOutOfMemory osztály az Exception-ből származik, és leírja azt a helyzetet, ahol a szabad RAM kimerült.
Az alábbi táblázat a SysUtils modulban deklarált standard kivételosztályokat mutatja. Ezek a hibák szinte teljes skáláját fedezik. Ha még mindig nem elegendőek, kiválaszthatja az Exception osztályból vagy örököseiről származó új kivételosztályokat.
Kivétel osztály
Egy "csendes" kivétel, amelyet a többszörös beágyazott blokkok vagy szubrutinok többszintű kilépéséhez használtak. Ugyanakkor nem jelenik meg hibaüzenet a képernyőn. EAbort kivétel létrehozásához meg kell hívnia a normál Megszakítási eljárást.
Hiba történt a fájl vagy az I / O eszköz elérésekor. A hibakód az ErrorCode mezőben található.
Kivételes helyzet, amely a programon kívül esik, például az operációs rendszerben.
Olyan kivételes helyzet, amely a programon kívül történt, például egy C ++-ban kifejlesztett DLL könyvtárban.
A dinamikus memóriával való együttműködés során előforduló kivételek általános csoportja. Alapvető az EOutOfMemory és EInvalidPointer osztályokhoz. Az ebbe az osztályba tartozó kivételes helyzetek (és az összes leszármazottja) létrehozása teljesen a Delphi környezetébe tartozik, ezért ne hozzon létre ilyen kivételes helyzeteket az emelőművelettel.
A szabad RAM kimerült (lásd: EHeadException).
Megpróbáltunk érvénytelen mutatót felszabadítani (lásd: EHeadException). Ez általában azt jelenti, hogy a mutató már megjelent.
Az általános számítási aritmetikai általános kivételosztály, amelyből az EDivByZero, az ERangeError és az EIntOverflow osztályok generálódnak.
Kísérlet az egész szám szétválasztására.
A megfelelő kezelő keresése egymás után történik, amíg a kivételosztály kompatibilis az on utasításban megadott osztálytal. Miután megtalálta a kezelőt, a szó mögött lévő operátort végrehajtja, és a vezérlés átkerül a kivételével. végén. Ha a kivétel nem vonatkozik a megadott osztályokra, akkor az ellenőrzés átkerül a külső próbatestre. kivéve. végét, és a kezelőt keresik benne.
Megjegyezzük, hogy a nyilatkozatok sorrendje jelentős, mivel a kivétel-felismerésnek magántulajdonú osztályoktól a közös osztályokig kell történnie, más szóval a leszármazottaktól az őseiig. Mi ez az oka? Most meg fogja érteni. Képzeld el, hogy megváltoztatod a fenti példában szereplő utasítások sorrendjét, ha figyelembe vesszük, hogy az EMathError osztály az alaposztály az EZeroDivide számára. A válasz egyszerű: az EMathError kezelő elnyeli a valós matematika minden hibáját, beleértve az EZeroDivide-t is. ennek eredményeképpen az EZeroDivide kezelő soha nem fog végrehajtani.
A program legmagasabb szintjén szükség lehet minden kivétel elfogadására, így bármilyen elszámolatlan hiba esetén az alkalmazás helyesen leállítható. Ehhez az úgynevezett alapértelmezett kivételkezelőt használják. A kimondott kivonatok után a kivételével, a másik kulcsszóval kezdődik:
4.3.3. Kivételkezelési példa
A kivételkezelés példájaként vegye figyelembe két funkciót: a StringToCardinal és a StringToCardinalDef.
A StringToCardinal függvény átalakítja a karakterláncot Cardinal típusúvá. Ha az átalakítás nem lehetséges, akkor a függvény kivételt hoz létre az EConvertError osztály számára.
A StringToCardinalDef függvény szintén átalakítja a karakterláncot egy bíboros típushoz, de a StringToCardinal függvényektől eltérően nem hoz létre kivételt. Ehelyett lehetővé teszi a sikertelen konverziós kísérlet esetén megadott érték megadását:
A forráskód számhoz való konvertálásához használja a fent meghatározott StringToCardinal függvényt. Ha kivétel történik a konverzió során, a StringToCardinalDef függvény "elnyeli", amely ebben az esetben az alapértelmezett paraméter értékét adja vissza. Ha van valami más hiba (nem EConvertError), akkor az ellenőrzés átkerül a külső kivételkezelő blokkra, amelyről a StringToCardinalDef függvényt hívták.
A példa nagyon egyszerű, de a hagyományos hibakezelés előtt kivételes helyzetek előnyeit mutatja. Képzeljünk el olyan komplex számításokat, amelyek egy sor operátorból állnak, amelyek mindegyikében hiba léphet fel. Mennyire nehéz lesz a hibák kezelése többszörös, ha kimutatásokat és egyszerű próbaverziót tartalmaz.
4.3.4. Kivételes helyzet megismétlése
Azokban az esetekben, amikor egy védett blokk nem tudja teljesen kezelni a kivételt, csak a munkájának részét veszi fel, és folytatja a kivételt úgy, hogy annak feldolgozása a külső védett blokknal folytatódjon:
Ha a külső védett blokkok egyike sem dolgozta fel a kivételt, akkor az ellenőrzés átkerül az általános kivételkezelőre, amely véget vet az alkalmazásnak.
4.3.5. Hozzáférés a kivételt leíró objektumhoz
Az eltérés kezelése megkövetelheti a hozzáférést egy olyan objektumhoz, amely leírja ezt a helyzetet, és tartalmaz egy hibakódot, a hiba szöveges leírását stb. Ebben az esetben a kiterjesztett kezelői rekordot használják:
Az E változó kivétel objektum, a ShowMessage az eljárás a DIALOG modulra, megjelenítve egy kis ablakot szöveggel és egy OK gombot a képernyőn. A karakterlánc Üzenet tulajdonsága az Exception osztályban van meghatározva. a hiba szöveges leírását tartalmazza. Az üzenet szövegének kezdeti értéke meg van adva a kivétel objektum megalkotásakor.
Ne feledje, hogy a kivétel kezelése után a megfelelő objektum felszabadítása automatikusan történik, erre nincs szükség.
4.4. A lekötött források védelme a veszteségtől
4.4.1. Erőforrás szivárgás és védelem tőle
A kivétel mechanizmussal létrehozott programoknak szigorú szabályokat kell betartaniuk olyan források, mint a memória, a fájlok és az operációs rendszer erőforrásainak felosztására és kiadására.
Képzelje el a helyzetet: egy alprogram egy bizonyos erőforrást osztozik, de egy kivétel leállítja annak végrehajtását, és az erőforrás szabadon marad. Még ha azt is gondolnánk, hogy ez szörnyű, akkor ez a hiba vezethet: memória szivárgás, fájlleírók, az operációs rendszer más erőforrásai. Ezért a forrásokat védeni kell a kivételes helyzetektől. Ehhez a Delphi környezet védett blokkjának egy másik változata van:
Ennek a blokknak az a sajátossága, hogy a végső szakasz. a vég mindig végrehajtásra kerül, függetlenül attól, hogy a kivétel történik-e vagy sem. Ha a próba szakasza bármely kijelentése. Végül kivételt hoz létre, a végső szakasz először végrehajtásra kerül. végén. úgynevezett befejezési szakasz (források kiadása), majd az ellenőrzés átkerül egy külső védett blokkra. Ha minden védett operátort hiba nélkül hajtanak végre, akkor a végződés is működik, de az ellenőrzést az azt követõ üzemeltetõ továbbítja. Ne feledje, hogy a végső szakasz. a vég nem kezeli a kivételt, nem rendelkezik annak észlelésével, és nem rendelkezik hozzáféréssel a kivétel objektumhoz.
4.2. Ábra. A próbálkozás logikája ... kivéve a végső kijelentést
A próbablokk. végül. másik fontos jellemzője. Ha ez kerül a ciklusban, a hívást a biztonságos blokk szünet eljárást azzal a céllal, egy idő előtti elhagyása a ciklus vagy a Folytatás eljárást annak érdekében, hogy átmenet a következő iterációban a hurok végül megadja az első részben. végén. majd a megfelelő átmenet már végrehajtásra került. Ez a kijelentés az Exit (kilépés a szubrutinból) eljárásra is érvényes.
Ahogy azt a gyakorlat mutatja, a szubrutinok gyakran több erőforrást osztanak ki egyszerre, és együtt használják őket. Ilyen esetekben beágyazott próbatesteket használnak. végül. vége:
Ezenkívül sikeresen kombinálhatja a próbálkozó blokkokat. végül. és próbáld ki. kivéve. end for resource protection és a kivételkezelés.
4.5. találatok
Ebben a fejezetben sokat tanultak a rendkívüli helyzetekről és a velük való foglalkozásról. Most a programjai minden bizonnyal méltó visszautasítást adnak nemcsak a leginkább nyers felhasználónak, hanem a fából készült számítógépének is. Ez egyébként az egyik szükséges tulajdonság, amely lehetővé teszi, hogy a programot jó osztályként osztályozza. Emlékezzünk arra is, hogy itt csak a futási hibákat vetettük szemügyre, ezért ne felejtsük el elolvasni a 10. fejezetet, amely a logikai hibák elleni küzdelmet tárgyalja.