exception safety

Üdvözlöm, Ön a exception safety szó jelentését keresi. A DICTIOUS-ban nem csak a exception safety szó összes szótári jelentését megtalálod, hanem megismerheted az etimológiáját, a jellemzőit és azt is, hogyan kell a exception safety szót egyes és többes számban mondani. Minden, amit a exception safety szóról tudni kell, itt található. A exception safety szó meghatározása segít abban, hogy pontosabban és helyesebben fogalmazz, amikor beszélsz vagy írsz. Aexception safety és más szavak definíciójának ismerete gazdagítja a szókincsedet, és több és jobb nyelvi forráshoz juttat.

Főnév

exception safety (tsz. exception safeties)

  1. (informatika) Kivételbiztonság azt jelenti, hogy a program egy kivétel dobása után is konzisztens állapotban marad. A C++ nyelv lehetővé teszi, hogy hibakezelésre trycatch blokkokkal és throw utasítással kivételeket használjunk – ezek megzavarhatják a normál vezérlésmenetet. Az exception safety garantálja, hogy a kivételek ellenére ne szivárogjon memória, ne romoljon el az objektum állapota, és a program biztonságosan folytatható vagy lezárható legyen.



🛡️ A kivételbiztonság szintjei (Herb Sutter szerint)

C++-ban négy klasszikus szintet különböztetünk meg:



✅ 1. No-throw guarantee (erős garancia)

A művelet garantáltan nem dob kivételt.

  • Erre példa lehet destruktorok vagy swap() függvények megvalósítása.
  • Használat: konténerek, std::vector::resize, std::unique_ptr
void biztonsagos() noexcept {
    // semmi nem dobhat
}

Az noexcept kulcsszó C++11-től garantálja ezt.



🔄 2. Strong guarantee (visszavonhatóság)

Ha kivétel történik, az objektum eredeti állapota megmarad.

  • A művelet vagy teljesen sikerül, vagy nem változik semmi.
  • Ez gyakran jelentős többletmunkát jelent, pl. ideiglenes objektumok használatával.

Példa:

std::vector<int> v = {1, 2, 3};
try {
    v.insert(v.begin(), 42); // ha nem sikerül, v változatlan marad
} catch (...) {
    // v nem sérült
}

🔁 3. Basic guarantee (minimális biztonság)

A művelet után az objektum érvényes, de az állapota megváltozhat.

  • Nem történik memória- vagy erőforrásszivárgás.
  • A program stabil, de az eredmények nem mindig garantáltak.

Példa:

void push(int x) {
    data.push_back(x); // ha dob kivételt, az objektum akkor is használható
}

❌ 4. No guarantee (nincs garancia)

Kivétel esetén az objektum érvénytelen állapotba kerülhet.

  • Ez kerülendő.
  • Csak akkor elfogadható, ha nem lehet másképp megoldani, és dokumentálva van.



🧠 Miért fontos?

  • Stabil programozás: A kivételbiztos kód nem omlik össze váratlanul.
  • Erőforráskezelés: Megakadályozható memória, fájl, mutex szivárgás.
  • Karbantarthatóság: Az ilyen kód könnyebben debugolható és bővíthető.
  • Standard könyvtár: A C++ STL osztályai nagy részben kivételbiztosak.



📦 Példa: nem biztonságos kód

void nemBiztonsagos(std::vector<int>& v) {
    v.push_back(10);       // lehet kivétel: memória!
    v = 999;            // csak akkor hajtódik végre, ha nem volt kivétel
}

Ha push_back() kivételt dob, v = 999 már nem fut le → az állapot félbemaradt lehet.



🔄 Megoldás: strong guarantee RAII-vel

void biztonsagos(std::vector<int>& v) {
    std::vector<int> temp = v;
    temp.push_back(10);      // ha ez elbukik, v változatlan
    temp = 999;
    v.swap(temp);
}

🧰 Eszközök a kivételbiztonsághoz

RAII (Resource Acquisition Is Initialization)

  • Az erőforrásokat (memória, fájl) olyan objektumhoz rendeljük, ami destruktorban felszabadítja azokat.
  • Ha kivétel történik, a destruktor automatikusan fut le → nincs szivárgás.
std::unique_ptr<int> ptr(new int(42)); // automatikus felszabadítás

Smart pointerek

  • std::unique_ptr, std::shared_ptr kivételbiztonságot adnak.
  • Automatikusan elvégzik a delete-et, akkor is, ha kivétel történik.



noexcept kulcsszó (C++11+)

Azt jelzi a fordítónak és programozóknak, hogy egy függvény nem dob kivételt.

void torol() noexcept;       // garantáltan nem dob kivételt

A std::swap, move műveletek noexcept-ként működnek hatékonyan, különben a konténerek például másolni fognak move helyett.



🧪 STL példák

std::vector::push_back

  • Ha új tárhely kell → memóriaallokáció → kivételt dobhat → basic guarantee

std::vector::resize

  • Ha T konstruktor kivételmentes → strong guarantee



🔄 Operátorok és kivételbiztonság

Az operátorokat, mint operator=, operator+, érdemes kivételbiztosan implementálni:

MyClass& operator=(const MyClass& other) {
    if (this != &other) {
        MyClass temp(other);
        swap(temp); // strong guarantee
    }
    return *this;
}

📋 Tippek a kivételbiztos kódhoz

Tipp Miért hasznos
Használj try/catch-et csak magas szinten Ne tömd tele kivételkezeléssel a kis függvényeket
RAII mindenre Erőforrás- és állapotkezelés automatikusan
Kerüld a kivételeket destruktorban Előfordulhat, hogy másik kivétel már aktív
Preferáld noexcept-et Gyorsabb és megbízhatóbb
Használj másolás/move-and-swap idiomát Erős garanciához kiváló



❓ Mi történik, ha kivétel van a destruktorban?

Kritikus helyzet!

Ha egy kivétel történik egy másik kivétel közben (pl. destruktorban), a program terminate()-et hív → leállás.

Ezért:

~MyClass() noexcept {
    try {
        // műveletek
    } catch (...) {
        // csendben elnyeli a hibát
    }
}

🔚 Összefoglalás

Fogalom Leírás
Exception safety Biztonságos viselkedés kivételek esetén
No-throw Semmilyen kivételt nem dob
Strong Vagy sikerül, vagy nem változik semmi
Basic Érvényes, de módosulhat az állapot
No guarantee Semmit nem garantál
Eszközök RAII, smart pointer, swap idiom, noexcept
STL viselkedés Jellemzően legalább basic guarantee



💬 Zárógondolat

A kivételbiztonság nemcsak „extra védelem”, hanem alapfeltétele a megbízható programoknak. A modern C++ lehetővé teszi, hogy erős garanciákat adjunk, és a helyes erőforrás-kezeléssel és noexcept-tel stabil és hatékony kódot írjunk – még akkor is, ha a dolgok félremennek.