Sobes.tech
Middle+

Mit tud az kivételek biztonsági garanciáiról?

sobes.tech MI

Válasz az MI-től

Az kivételbiztonsági garanciák meghatározzák a függvény viselkedését kivétel esetén. Négy szintet különböztetünk meg:

  1. Alap garancia (Basic guarantee): Ha a függvény kivételt dob, a program érvényes állapotban marad. Az erőforrások nem vesznek el (pl. memória felszabadul), de az objektumok pontos állapota lehet ismeretlen. Tovább lehet vele dolgozni.

    // Alap garancia példája
    void basic_guarantee_function(std::vector<int>& vec, int value) {
        // Kivétel fordulhat elő beszúráskor
        vec.push_back(value); 
        // Ha kivétel történik, a vec bizonytalan állapotban lehet (részben módosított),
        // de a vec-hez lefoglalt memória helyesen lesz felszabadítva kilépéskor.
    } 
    
  2. Erős garancia (Strong guarantee): Ha a függvény kivételt dob, a program állapota ugyanaz marad, mint a függvény hívása előtt. Minden változtatás visszavonódik.

    // Erős garancia példája
    // A Copy-and-Swap idiom használatával biztosítjuk az erős garanciát
    class Resource {
        int* data;
        size_t size;
    public:
        Resource(size_t s) : size(s), data(new int[s]) {}
        ~Resource() { delete[] data; }
        Resource(const Resource& other) : size(other.size), data(new int[other.size]) {
            std::copy(other.data, other.data + size, data); // Kivételt dobhat
        }
        Resource& operator=(Resource other) // Értékátvitel
        {
            swap(*this, other); // Nem dob kivételt
            return *this;
        }
        friend void swap(Resource& first, Resource& second) noexcept {
            using std::swap;
            swap(first.data, second.data);
            swap(first.size, second.size);
        }
        // ... egyéb tagfüggvények
    };
    
    void strong_guarantee_function(Resource& res, size_t new_size) {
        Resource temp(new_size); // Ha itt kivétel történik, res nem változik
        res = temp;               // A túlterhelt = operátor használata, amely garantálja az erős garanciát
    }
    
  3. Kivételmentes garancia (No-throw guarantee): A függvény garantáltan nem dob kivételt. Ezek a függvények noexcept specifikátorral vannak ellátva.

    // Kivételmentes példa
    void no_throw_function() noexcept {
        // Nincs olyan művelet, ami kivételt dobhatna
        int a = 5;
        int b = 10;
        int c = a + b;
    }
    
  4. Hibajavítási garancia (Failure guarantee): A kivételbiztonság kontextusában néha említik ezt a szintet, ami azt jelenti, hogy a függvény a programot nem meghatározott állapotba hagyhatja, erőforrás-szivárgás vagy hibák lehetnek. Ez gyakorlatilag a garanciák hiánya. Ilyen viselkedést kerülni kell.

A kivételbiztonsági garanciák fontossága abban rejlik, hogy megbízható és előre látható kódot hozunk létre, amely helyesen kezeli a hibákat és az erőforrásokat még kivétel esetén is. A választott garancia szintje a művelet kritikus voltától, a visszavonás költségétől és a kivétel valószínűségétől függ.

Garázási táblázat:

Garancia Állapot kivétel esetén Adatok integritása Erőforrás-szivárgás
Alap Érvényes, de nem meghatározott Nem garantált Nem
Erős Nem változik (mint a hívás előtt) Megmarad Nem
Kivételmentes Soha nem fordul elő (nincs kivétel) N/A N/A
Hibajavítás (hiány) Nem meghatározott, esetleg sérülés vagy hibák Nem garantált Lehetséges