Ugrás a tartalomhoz

C++ exception handling

A Wikiszótárból, a nyitott szótárból


Főnév

C++ exception handling (tsz. C++ exception handlings)

  1. (informatika) kivételkezelés

A kivételkezelés (exception handling) C++-ban egy olyan mechanizmus, amely lehetővé teszi a hibák kezelését és a program összeomlásának elkerülését. A kivételek (exceptions) segítségével egy program fel tudja ismerni és kezelni a váratlan eseményeket, például egy fájl hiányát vagy egy 0-val való osztást.



1. A kivételkezelés alapjai C++-ban

C++-ban a kivételkezelés három kulcsszóból áll:

  • try – A kód, amelyben a kivétel előfordulhat.
  • throw – A kivétel kiváltása.
  • catch – A kivétel elkapása és kezelése.

Alap példa kivételkezelésre

#include <iostream>

void osztas(int a, int b) {
    if (b == 0) {
        throw "Hiba: 0-val nem lehet osztani!"; // Kivétel kiváltása
    }
    std::cout << "Eredmény: " << a / b << std::endl;
}

int main() {
    try {
        osztas(10, 2);  // Nincs kivétel
        osztas(5, 0);   // Kivétel keletkezik
    }
    catch (const char* hiba) {
        std::cerr << "Kivétel elkapva: " << hiba << std::endl;
    }

    return 0;
}

🔹 Mi történik itt? - Ha a b == 0, akkor egy kivétel (throw) történik. - A try blokkban hívjuk meg a osztas() függvényt. - Ha kivétel keletkezik, akkor a catch blokk elkapja és kiírja a hibaüzenetet.



2. Kivétel kiváltása (throw) különböző típusokkal

A throw segítségével bármilyen típusú adatot kiválthatunk, például egész számot, szöveget, vagy akár egyedi osztályokat is.

Különböző kivétel típusok kezelése

#include <iostream>

void teszt(int szam) {
    if (szam == 0)
        throw 0; // Egész szám kivétel
    else if (szam == 1)
        throw std::string("Szöveges kivétel!");
    else
        throw std::runtime_error("Standard kivétel: std::runtime_error");
}

int main() {
    try {
        teszt(1); // Kivételt fog generálni
    }
    catch (int e) {
        std::cerr << "Egész szám kivétel: " << e << std::endl;
    }
    catch (std::string& e) {
        std::cerr << "Szöveges kivétel: " << e << std::endl;
    }
    catch (std::exception& e) {
        std::cerr << "Standard kivétel: " << e.what() << std::endl;
    }

    return 0;
}

🔹 Mi történik itt? - Ha szam == 0, akkor egy int típusú kivételt dobunk. - Ha szam == 1, akkor egy std::string kivételt dobunk. - Egyébként egy std::runtime_error kivételt dobunk, amely a std::exception osztály leszármazottja.



3. std::exception és saját kivételosztály létrehozása

A C++ rendelkezik egy beépített std::exception osztállyal, amelyből saját kivételeket hozhatunk létre.

Saját kivételosztály létrehozása

#include <iostream>
#include <exception>

// Saját kivételosztály, amely örököl az std::exception-ből
class SajatKivetel : public std::exception {
public:
    const char* what() const noexcept override {
        return "SajatKivetel: Hiba történt!";
    }
};

void teszt() {
    throw SajatKivetel(); // Saját kivétel kiváltása
}

int main() {
    try {
        teszt();
    }
    catch (const std::exception& e) {
        std::cerr << "Kivétel elkapva: " << e.what() << std::endl;
    }

    return 0;
}

🔹 Mit csinál ez a kód? - Létrehozunk egy SajatKivetel osztályt, amely az std::exception osztályból öröklődik. - Az what() függvény adja vissza a kivétel hibaüzenetét. - A kivételt a catch (std::exception&) segítségével elkapjuk.



4. noexcept – Kivétel nélküli függvények

Ha biztosak vagyunk abban, hogy egy függvény nem fog kivételt dobni, akkor használhatjuk a noexcept kulcsszót.

Példa noexcept használatára

#include <iostream>

void biztonsagosFuggveny() noexcept {
    std::cout << "Ez a függvény biztosan nem dob kivételt." << std::endl;
}

int main() {
    biztonsagosFuggveny();
    return 0;
}

🔹 Mit csinál a noexcept? - Megmondja a fordítónak, hogy a függvény nem dob kivételt, így a fordító optimalizálhatja a kódot. - Ha mégis kivétel keletkezik egy noexcept függvényben, a program összeomlik (std::terminate()).



5. try-catch a konstruktorban

Ha egy konstruktor kivételt dob, akkor az objektum nem fog létrejönni.

Példa konstruktorban dobott kivételre

#include <iostream>
#include <stdexcept>

class Auto {
public:
    Auto(int evjarat) {
        if (evjarat < 2000)
            throw std::invalid_argument("Túl régi autó!");
        std::cout << "Autó létrehozva, évjárat: " << evjarat << std::endl;
    }
};

int main() {
    try {
        Auto a1(1995); // Kivételt fog dobni
    }
    catch (const std::exception& e) {
        std::cerr << "Kivétel elkapva: " << e.what() << std::endl;
    }

    return 0;
}

🔹 Fontos tudni: - Ha egy konstruktor kivételt dob, az objektum sosem jön létre.



Összegzés

✅ A kivételkezelés (try-catch-throw) segít a programhibák kezelésében és megelőzésében.
✅ A throw segítségével bármilyen típusú kivételt kiválthatunk.
✅ A catch blokkok különböző típusokat foghatnak el (int, std::string, std::exception).
✅ A std::exception osztályból örökölve saját kivételosztályokat hozhatunk létre.
✅ A noexcept kulcsszó garantálja, hogy egy függvény nem dob kivételt.
✅ A konstruktorban dobott kivételek meghiúsítják az objektum létrehozását.