try block
Főnév
try block (tsz. try blocks)
- (informatika) A
tryblokk 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.
1. try blokk alapjai
A 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.
Egyszerű 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.
2. Több catch blokk használata
Ha egy try blokk többféle kivételt is kiválthat, akkor több catch blokkot is írhatunk.
Példa különböző kivételek elkapására
#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.
3. try blokk konstruktorban
A try blokk konstruktorokban is használható, ha az objektum inicializálásánál kivétel fordulhat elő.
Példa: Kivétel a konstruktorban
#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.
4. try blokk destruktorban
A 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.
Hibás kód – Ne csináljuk így!
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;
}
}
};
5. try blokk tömbök és dinamikus memória esetén
A 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.
Példa: Dinamikus memória felszabadítása kivétel esetén
#include <iostream>
void teszt() {
int* tomb = new int[5]; // 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.
6. try blokk STL és std::exception esetén
A C++ szabványos könyvtára (STL) sok kivételt dob, például std::out_of_range és std::invalid_argument.
Példa: 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.
Összegzés
✅ 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.