Ce face std::exception
Toate excepțiile aruncate de biblioteca standard moștenesc std::exception: std::runtime_error, std::out_of_range, std::bad_alloc etc. De aceea un singur catch (const std::exception& e) le prinde pe toate.
Metoda virtuală what() returnează un text care descrie eroarea. Pentru excepțiile standard, textul este cel dat la aruncare (throw std::runtime_error("mesaj")) sau unul ales de bibliotecă.
Excepțiile se prind mereu prin referință const (const std::exception&). Prinse prin valoare, ar fi copiate și „tăiate” la tipul de bază (object slicing), iar what() ar pierde mesajul specific. Pentru sintaxa try/catch/throw, vezi paginile acestor cuvinte cheie.
Ce returnează
what() returnează un const char* cu mesajul erorii.
Exemple
Exemplul 1: Un singur catch pentru toate erorile standard
Textele pentru vector::at și stoi sunt alese de biblioteca standard (aici libc++) și pot diferi la alte compilatoare.
#include <exception>
#include <print>
#include <stdexcept>
#include <string>
#include <vector>
void incearca(int caz) {
try {
if (caz == 1) {
std::vector<int> v{1, 2, 3};
std::println("{}", v.at(10));
} else if (caz == 2) {
std::println("{}", std::stoi("doisprezece"));
} else {
throw std::runtime_error("serverul nu răspunde");
}
} catch (const std::exception& e) {
std::println("Eroare la cazul {}: {}", caz, e.what());
}
}
int main() {
for (int caz = 1; caz <= 3; ++caz) incearca(caz);
}
Rezultat
Eroare la cazul 1: vector
Eroare la cazul 2: stoi: no conversion
Eroare la cazul 3: serverul nu răspunde
Exemplul 2: Excepție proprie care moștenește std::exception
#include <exception>
#include <print>
#include <string>
class StocInsuficient : public std::exception {
public:
StocInsuficient(std::string produs, int disponibil)
: mesaj_("Stoc insuficient pentru " + produs + " (disponibil: " + std::to_string(disponibil) + ")") {}
const char* what() const noexcept override { return mesaj_.c_str(); }
private:
std::string mesaj_;
};
void comanda(int cantitate) {
const int stoc = 3;
if (cantitate > stoc) throw StocInsuficient("cafea", stoc);
std::println("Comandă acceptată: {} buc.", cantitate);
}
int main() {
try {
comanda(2);
comanda(5);
} catch (const std::exception& e) {
std::println("{}", e.what());
}
}
Rezultat
Comandă acceptată: 2 buc.
Stoc insuficient pentru cafea (disponibil: 3)
Greșeli frecvente
- Prinzi excepția prin valoare:
catch (std::exception e). Obiectul este „tăiat” la clasa de bază șiwhat()dă un mesaj generic. Scriecatch (const std::exception& e). - Pui
catch (const std::exception&)înaintea unuicatchpentru o clasă derivată. Blocurile se verifică în ordine, deci cel specific nu mai este atins niciodată; pune întâi excepțiile specifice.
Comenzi înrudite
try, catch: try marchează codul care poate arunca o excepție, iar blocurile catch prind și tratează excepțiile de un anumit tip.throw: Aruncă o excepție: oprește execuția normală și trimite eroarea la cel mai apropiat catch potrivit.std::runtime_error: Excepție pentru erorile care apar doar la rulare, din cauze externe: fișier lipsă, rețea, date greșite.noexcept: Marchează o funcție care promite că nu aruncă excepții; ca operator, verifică la compilare dacă o expresie poate arunca.