try block (tsz. try blocks)
try
blokk C++-ban a kivételkezelés (exception handling) egyik alapvető eleme. Segítségével a program biztonságosan el tudja kapni és kezelni a hibákat, hogy elkerülje az összeomlást.
try
blokk alapjaiA try
blokk tartalmazza azt a kódot, amelyben kivétel keletkezhet. Ha a try
blokkban hiba történik, a program a megfelelő catch
blokkba ugrik, ahol kezelhetjük a kivételt.
try-catch
példa#include <iostream>
int main() {
try {
int szam = 10;
if (szam > 5) {
throw "Hiba: A szám nagyobb, mint 5!";
}
std::cout << "Ez a sor nem fog lefutni, ha kivétel keletkezik." << std::endl;
}
catch (const char* hiba) {
std::cerr << "Kivétel elkapva: " << hiba << std::endl;
}
std::cout << "Program folytatódik a kivétel után." << std::endl;
return 0;
}
🔹 Mi történik itt? - A try
blokkban kivételt (throw
) váltunk ki, ha a szám nagyobb, mint 5. - A throw
után a try
blokk futása azonnal megszakad, és a program a catch
blokkba ugrik. - A program ezután nem áll le, hanem folytatja a végrehajtást a catch
blokk után.
catch
blokk használataHa egy try
blokk többféle kivételt is kiválthat, akkor több catch
blokkot is írhatunk.
#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 3.14; // Lebegőpontos kivétel
}
int main() {
try {
teszt(1);
}
catch (int e) {
std::cerr << "Egész szám kivétel elkapva: " << e << std::endl;
}
catch (std::string& e) {
std::cerr << "Szöveges kivétel elkapva: " << e << std::endl;
}
catch (...) { // Általános kivétel elkapó
std::cerr << "Ismeretlen kivétel történt!" << std::endl;
}
return 0;
}
🔹 Mi történik itt? - Háromféle kivétel keletkezhet (int
, std::string
, double
). - A megfelelő catch
blokk csak azt a típust kapja el, amely illeszkedik. - Az utolsó catch (...)
blokk minden más kivételt elkap, ha az előző catch
blokkok nem illeszkednek.
try
blokk konstruktorbanA try
blokk konstruktorokban is használható, ha az objektum inicializálásánál kivétel fordulhat elő.
#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 a konstruktorból: " << e.what() << std::endl;
}
return 0;
}
🔹 Fontos tudni: - Ha egy konstruktor kivételt dob, az objektum nem jön létre. - A kivételt a catch
blokkban kell kezelni, különben a program összeomlik.
try
blokk destruktorbanA destruktorban (~
operátorral jelölt függvényben) nem ajánlott kivételt dobni, mert ha egy kivétel nem kezelődik, akkor a program összeomlik.
class Pelda {
public:
~Pelda() {
throw "Destruktorban kivétel történt!"; // 🚨 ROSSZ GYAKORLAT!
}
};
🔹 Miért rossz? - Ha egy objektum destruktorában kivétel keletkezik, és egy másik kivétel már aktív, akkor a program azonnal leáll (std::terminate()
).
✅ Megoldás: Ha kivételt kell kezelni egy destruktorban, fogjuk el try-catch
segítségével:
class Pelda {
public:
~Pelda() {
try {
throw "Destruktorban kivétel történt!";
}
catch (...) {
std::cerr << "Destruktorban keletkezett kivétel elkapva!" << std::endl;
}
}
};
try
blokk tömbök és dinamikus memória eseténA try
blokk segíthet megelőzni a memória-szivárgást, ha egy kivétel miatt a lefoglalt memóriát el kell engedni.
#include <iostream>
void teszt() {
int* tomb = new int; // Dinamikus memóriafoglalás
try {
throw std::runtime_error("Hiba történt!");
}
catch (...) {
delete tomb; // Memória felszabadítása
std::cerr << "Kivétel elkapva és a memória felszabadítva!" << std::endl;
}
}
int main() {
teszt();
return 0;
}
🔹 Miért fontos? - Ha a kivételt nem kezeljük, akkor a memóriafoglalás nem lesz felszabadítva és memória-szivárgás történik. - A catch
blokk biztosítja, hogy a memória felszabaduljon.
try
blokk STL és std::exception
eseténA C++ szabványos könyvtára (STL
) sok kivételt dob, például std::out_of_range
és std::invalid_argument
.
std::vector
kivételkezelés#include <iostream>
#include <vector>
#include <stdexcept>
int main() {
try {
std::vector<int> v = {1, 2, 3};
std::cout << v.at(5) << std::endl; // Hibás indexelés
}
catch (const std::out_of_range& e) {
std::cerr << "Kivétel elkapva: " << e.what() << std::endl;
}
return 0;
}
🔹 Mit csinál? - A v.at(5)
túlindexeli a vektort, és std::out_of_range kivételt dob. - A catch
blokk ezt kezeli, és megakadályozza az összeomlást.
✅ A try
blokk védi a kódot a kivételektől.
✅ A throw
kiváltja a hibát, amelyet a catch
blokk kezel.
✅ Több catch
blokk lehet, ha különböző kivételeket kezelünk.
✅ A destruktorokban tilos kivételt dobni – ha kell, fogjuk el helyben.
✅ Memóriafoglalásnál a try
blokk segíthet elkerülni a memória-szivárgást.