stdexcept class
Főnév
stdexcept class (tsz. stdexcept classes)
- (informatika) A C++ kivételkezelő mechanizmusának (exception handling) egyik központi eleme a
<stdexcept>és<exception>fejlécben definiált osztályhierarchia. Ezek az osztályok egységes felületet biztosítanak a futás közbeni hibák jelzéséhez és kezeléséhez, valamint segítik a kód olvashatóságát és karbantarthatóságát. Ebben a szövegben részletesen áttekintjük a legfontosabb osztályokat, azok viszonyát, használatát, testreszabását, és a hozzájuk kapcsolódó legjobb gyakorlatokat.
A C++ kivételhierarchia áttekintése
A C++-ban minden kivétel típusa implicit módon vagy expliciten örökli az alap osztálytól, a std::exception-től (definiálva a <exception>-ben). A <stdexcept> fejléc kiegészíti ezt további specializált osztályokkal, hogy a különböző hibajelenségekhez megfelelően tükröződő típusokat kínáljon.
std::exception ├─ std::logic_error │ ├─ std::invalid_argument │ ├─ std::domain_error │ ├─ std::length_error │ └─ std::out_of_range └─ std::runtime_error ├─ std::range_error ├─ std::overflow_error └─ std::underflow_error
std::logic_error: A programozási logika hibáit reprezentálja, amelyeket általában a kód helytelen felépítése vagy érvelése okoz.std::runtime_error: Futásidejű hibák, külső környezeti tényezők (pl. fájlkezelés, hálózat) miatt bekövetkező kivételek.
std::exception és alapvető tulajdonságai
A std::exception az ős, amely az alábbi virtuális metódust definiálja:
virtual const char* what() const noexcept;
what(): Visszaad egy human–readable üzenetet a kivételről.noexcept: Biztosítja, hogy awhat()maga nem fog másik kivételt dobni.
Mivel minden szabványos kivétel ebből származik, egy egységes kezelőblokkban is el lehet kapni:
try {
// … kód, ami kivételt dobhat …
} catch (const std::exception& e) {
std::cerr << "Hiba: " << e.what() << '\n';
}
Ez a minta egyszerűsített, de nem tesz különbséget a különböző hibaszituációk között.
A <stdexcept> fejléc osztályai
std::logic_error és származékai
std::invalid_argument: Hibás argumentum átadásakor.std::domain_error: Matematikai függvények érvénytelen tartományában.std::length_error: Túl nagy hosszúságú adat esetén (például string, konténer).std::out_of_range: Indexelési hiba, amikor túllépünk egy tartományt.
#include <stdexcept>
#include <vector>
int safe_at(const std::vector<int>& v, size_t idx) {
if (idx >= v.size())
throw std::out_of_range("Index túl nagy: " + std::to_string(idx));
return v[idx];
}
std::runtime_error és származékai
std::range_error: Numerikus tartománytúllépés.std::overflow_error: Átfolyás (overflow) esetén.std::underflow_error: Alulfolyás (underflow) esetén.
double reciprocal(double x) {
if (x == 0.0)
throw std::domain_error("Nullával való osztás");
return 1.0 / x;
}
Kivételek dobása és kezelése
Dobás (
throw)- Végezze el a hibajelzést a lehető leghamarabb ott, ahol a hiba jelentkezik.
- Használjon részletes, informatív üzeneteket a
what()-ban.
Elkapás (
catch)Specifikus → általános sorrendben:
try { // ... } catch (const std::out_of_range& e) { // Speciális kezelés } catch (const std::exception& e) { // Általános kezelés }
Kerülje a
catch(...)általános fogást, hacsak nem valóban utolsó védvonalról van szó.
Újradobás (
rethrow)Ha a függvény nem tudja kezelni a kivételt, újra lehet dobni:
catch (const std::exception& e) { // naplózás throw; // eredeti kivétel továbbítása }
Egyéni kivételek definiálása
Ha a szabványos osztályok nem fedik le a domain-specifikus hibákat, készíthetünk sajátokat:
class FileParseError : public std::runtime_error {
public:
explicit FileParseError(const std::string& filename, int line)
: std::runtime_error("Hiba a fájlban: " + filename +
" sor: " + std::to_string(line)) {}
};
- Örököljünk
std::runtime_error-ből vagystd::logic_error-ből a hiba jellege szerint. - Adjuk át a hibaüzenetet a bázisosztálynak.
Kivételbiztonság és RAII
- Basic safety (alapszintű biztonság)
- Minden kivétel esetén az objektum invariáns megmarad.
- Strong safety (erős biztonság)
- Vagy sikeresen végrehajtódik a művelet, vagy semmi sem történik (rollback).
- No-throw safety
- Bizonyos műveletek soha nem dobhatnak kivételt (
noexcept).
- Bizonyos műveletek soha nem dobhatnak kivételt (
A RAII (Resource Acquisition Is Initialization) minta automatikusan kezeli az erőforrásokat (memória, fájl, mutex), még kivételek esetén is:
std::lock_guard<std::mutex> lock(mutex);
// garantáltan feloldódik a blokkon való kilépéskor
noexcept és teljesítmény
A
noexceptkulcsszóval jelezhetjük, hogy egy függvény nem dob kivételt:void func() noexcept { /* … */ }
noexceptesetén a fordító optimalizációkat végezhet (pl. move-eléseket), és a Standard Library konténerek is érzékelik, hogy biztonságosan mozgathatják az elemeket.A move-konstruktorokat és move-operatorokat érdemes
noexcept-ként definiálni, hogy a konténerek hatékonyabban működjenek.
Legjobb gyakorlatok összegzése
- Dobás a hibát észlelő rétegben, ne mélyebben vagy magasabban.
- Minimális javasolt kivételfogók: ahol tudjuk kezelni vagy kontextust adni.
- Használjunk specifikus kivételeket, ne csak
std::exception–t. - Ne dobjunk primitív típusokat (pl.
int,char*), csak osztályokat örökölve. - Dokumentáljuk, mely függvények dobnak kivételt és milyen feltételekkel.
- Mark upstream error: ha egy alacsonyabb szintű függvény dob, dokumentáljuk vagy csomagoljuk újra magasabb kontextusban.
noexceptmindenhol, ahol lehetséges, a teljesítmény és a biztonság érdekében.
Összefoglalás
A <stdexcept> és <exception> fejléc osztályai egységes, jól átgondolt eszköztárat kínálnak a C++ futásidejű és logikai hibáinak kezelésére. A megfelelő osztályválasztás, a specifikus kivételek használata, a részletes what()-üzenetek, továbbá a RAII és noexcept alkalmazása együtt erős, megbízható és karbantartható kódot eredményez. A gyakorlatban érdemes következetesen alkalmazni ezeket a mintákat, dokumentálni a dobható kivétel típusokat, és csak ott fogni el a kivételeket, ahol valóban tudjuk kezelni a hibát. A szabványos kivételek kiegészíthetők domain-specifikus, egyéni osztályokkal, amellyel még inkább szemantikus és karbantartható lesz a kivételkezelésünk.
- stdexcept class - Szótár.net (en-hu)
- stdexcept class - Sztaki (en-hu)
- stdexcept class - Merriam–Webster
- stdexcept class - Cambridge
- stdexcept class - WordNet
- stdexcept class - Яндекс (en-ru)
- stdexcept class - Google (en-hu)
- stdexcept class - Wikidata
- stdexcept class - Wikipédia (angol)