Kivételkezelés

Ilyen események a programnak a rendszer hibaüzenetével történő befejezéséhez vezetnek. A kivétel mechanizmus lehetővé teszi a program visszaállítását és végrehajtását.







A C ++ kivételek nem támogatják az aszinkron események feldolgozását (hardverhibák vagy megszakítások kezelése), de csak azokra a eseményekre szánták, amelyek a program eredményeként jelentkeznek és kifejezetten meg vannak határozva.

A kivételek a számítógépes folyamatot két részre bontják: vészhelyzet felismerése és feldolgozása.

· A hibát észlelő funkciók nem tudják, hogyan kell kijavítani, és a kód, amely ezt a funkciót használja, nem tudja meghatározni a hiba eredetét. Ez tényleges, ha több modulból álló könyvtári funkciókat és programokat használ,

· Ha hiba információt szeretne küldeni a hívó funkciónak, akkor nem kell visszatérési értéket, paramétereket vagy globális változókat használni.

A kivétel kezelésének eljárása:

· Hiba jelentkezik, és a függvény, ahol ez bekövetkezett, kivételt hoz létre,

· Az aktuális blokk végrehajtása megszűnik, a megfelelő kezelőt keresi és a vezérlő átkerül,

· Ha nem találja meg, hívják a szabványos befejezési funkciót, ami viszont felhívja az abort funkciót, amely megszakítja az aktuális folyamatot. Beállíthatja saját folyamat-befejezési funkcióját.

A híváscsomó olyan hívások sorozata, amelyeket felhívtak, de még nem fejeződött be.

Az összecsomagolás folyamata a memória felszabadítása a helyi változók és a visszatérő vezérlés a hívó funkció. A funkció végén a köteg le van húzva.

Mivel a vezérlést csak a funkció befejezése után lehet visszaadni a hívási pontra, a kivétel elkövetése után a végrehajtás nem folytatható a kivétel generálásának helyén.

A vezérlőblokk szintaxisa (a kód, amelyben a kivételt lehet dobni):

A próbatest olyan funkciókat is tartalmaz, amelyeket közvetlenül vagy közvetetten hívnak.

A kivétel létrehozásának szintaktikája:

A paraméter (kifejezés) átadja a kezelő számára a kivételt. A paraméter lehet állandó, változó vagy objektum. A paraméter (kifejezés) típusa határozza meg a felvetendő kivétel típusát.

Rendszerint kivétel a próbablokkban található funkciókban. Az ilyen kivételeket nem mindig lehet azonnal kezelni. Ebben az esetben a beágyazott ellenőrzött blokkokat használják, és a kivételt egy magasabb szintre adják át a dobási kulcsszó nélkül.

A kezelő szintaxisa (három rekordforma):

1. Alkalmazható, amikor a kivételnév a kezelő testében használatos bármely művelet elvégzésére (például a kivételre vonatkozó információk kiadása).

fogás (típusnév), ahol a típusparaméter a kivétel típusa.

2. A kezelőben lévő kivétel nevével kapcsolatos információk nem használatosak, csak a típus szerepet játszik.

3. A kezelő elfogja minden kivételt.

A kezelőket abban a sorrendben tekintik meg, amelyben írták őket, így egy ilyen típusú kezelőt minden más után kell elhelyezni.

A kezelőnek közvetlenül a próbatest mögött kell lennie. Egy vagy több kezelőt írhat fel a feldolgozott kivételek típusai szerint.

// Kezelje az int

fogás (const char *)





// A konst-char karakter kivételével *

// túlcsordulás kivétel kezelése

// Minden kezeletlen kivételt kezelni

A kivétel kezelése után az ellenőrzés az első operátorra kerül, amely közvetlenül a kivételkezelők mögött található. Ha a kísérleti blokk kivétele nem jött létre, akkor az összes kezelő kódját átadó vezérlő átkerül ugyanabba a pontba.

Miután létrehozta a kivételt a dobási függvény használatával, a C ++ végrehajtható könyvtár végrehajtja:

· A dobási paraméter egy példányának létrehozása statikus objektum formájában (a kivétel feldolgozásáig létezik);

· A köteg feloldása egy megfelelő kezelő (a helyi hatóköröket elhagyó helyi objektumok hívóinak eltávolítása) keresésére. Minden kezelőt minden szinten egymás után nézünk, a beltéri egységről a külsőre;

· Az objektum átvitele és a kezelő irányítása.

A kezelő akkor tekinthető meg, ha az eldobott objektum típusa:

· Megegyezik a fogási paraméterben megadott paraméterrel (T formában, const T, T formában írható vagy const T, ahol T a kivétel típusa);

· A fogási paraméterben megadott paraméterből származik (ha az örökséget a nyilvános hozzáférési kulcs segítségével végezték). Ezért a származtatott osztálykezelőket az alapkezelők előtt kell elhelyezni (különben soha nem adják át a kezelőnek).

· Olyan mutató, amely szabványos szabályokkal konvertálható, hogy a mutatókat a fogási paraméterben mutatós típusúvá alakítsa. A típusú üres mutatót az adott típusú mutatók kezelői után kell elhelyezni (bármely más típusú mutatót elrejti).

// Osztály, amely tájékoztat a létrehozásáról és megsemmisítéséről

ifstream ifs ("\\ INVALID \\ FÁJL \\ NÉV"); // Nyissa meg a fájlt

A program eredményei:

Adja meg a próbatestet

A kezelő const char * nevű volt, kivétel - Hiba történt a fájl megnyitásakor

A kivétel után felemelték a helyi objektum megsemmisítőjét, bár az f1 függvény vezérlése átadásra került a kezelőnek, ami a fő funkció. Az "Exit from the try-block" üzenet nem jelenik meg.

A kivétel mechanizmus lehetővé teszi az objektumok helyes elpusztítását hibák előfordulásakor. Ezért érdemes az erőforrásokat olyan osztályok formájában felosztani és felszabadítani, amelyeknek a konstruktora egy erőforrást oszt meg, és a destructor kiadja.

Egy példa egy fájl kezeléséhez szükséges osztály. Az osztály konstruktor megnyitja a fájlt, és a megsemmisítő bezárja. Hiba esetén a fájl helyesen lezárul és az adatok nem lesznek elveszítve.

A kivétel lehet szabványos vagy felhasználó által definiált típus. Nem szükséges globálisan definiálni ezt a típust - elég, hogy a kivétel generálásának és feldolgozásának pontján ismeretes.

Egy kivételt képviselő osztály egy osztályon belül írható le, amikor együtt dolgozik. Ennek az osztálynak a másolási konstruktorát nyilvánosnak kell nyilvánítani, különben lehetetlen létrehozni az objektum másolatát, ha kivételt generál (az alapértelmezett másolási konstruktor a nyilvános specifikálóval rendelkezik).

Kivételek a funkciókban

A függvényfejlécben kiválaszthatja azokat a kivételeket, amelyeket közvetlenül vagy közvetve generálhat. A kivételek típusai zárójelben vesszővel vannak elválasztva, a funkcióparaméterek mögött található kulcsszóhajtás után:

void fl () dob (int, const char *)

A fl függvény csak az int és const char * kivételével lehet kivételt, f2 - csak a mutató típus kivételét az Oops osztályhoz vagy származtatott osztályához.

Ha a dobás kulcsszó nincs megadva, a függvény kivételt generálhat. Egy üres lista azt jelenti, hogy a függvénynek nem szabad kivételt tenni:

// A funkció teste, amely nem ad kivételeket

A fejléc a függvény interfésze, így a kivétellisták megadása információval szolgál a használatához, és garantálja, hogy ha váratlan kivétel történik, akkor ez a helyzet észlelhető (a függvény közvetlenül vagy közvetve kivételt generálhat, amelyet a kezelőfelület nem ír le).

A váratlan kivétel előfordulása a normál függvény váratlan hívásához vezet, ami alapértelmezés szerint a befejezési függvényt hívja (2.3. Ábra). A set_unexpected függvény használatával beállíthatja a saját funkcióját, amelyet a megszüntetés helyett hívnak le, és meghatározza a program működését, ha váratlan kivétel történik.

A lezárás funkció alapértelmezés szerint felhívja az abort funkciót, amely befejezi a programot. A set_terminate funkció használatával beállíthatja saját funkcióját, amelyet a megszakítás helyett hívnak le, és meghatározza, hogy a program hogyan fejeződik be. A set_unexpected és set_terminate függvényeket a fejlécfájl írja le .

2.3. Ábra - Kivételkezelési algoritmus.

Kivételek nem része a függvény prototípusának. Ha egy származtatott osztályban felülír egy virtuális függvényt, kiválaszthat egy olyan kivételt tartalmazó listát, amely ugyanolyan vagy korlátozottabb, mint az alaposztály megfelelő funkciója.




Kapcsolódó cikkek