Historie van de kwestie:
Het mechanisme voor het verwerken van uitzonderingen werd geïntroduceerd in C++ om een betrouwbaardere en gestructureerdere foutafhandeling te waarborgen, in tegenstelling tot foutcodes. Door de jaren heen is de syntaxis uitgebreid en zijn er type-specifiers zoals noexcept toegevoegd voor controle over het annuleren van het gooi van uitzonderingen vanuit functies.
Probleem:
Onjuist omgaan met uitzonderingen leidt vaak tot geheugenlekken, onbepaald gedrag of crashes van toepassingen. Als het gooien van uitzonderingen uit constructors, destructors of bij het werken met bronnen niet wordt overwogen, ontstaat er een serieus probleem met de status van het programma.
Oplossing:
De basis syntaxis - het gebruik van try-catch. Uitzonderingen kunnen van elk type zijn, maar het wordt aanbevolen om gebruikers gedefinieerde uitzonderingen van std::exception te erven. Het sleutelwoord noexcept (C++11+) geeft aan dat een functie geen uitzonderingen mag gooien; het gooien van een uitzondering vanuit een noexcept-functie roept std::terminate() aan.
Voorbeeldcode:
#include <iostream> #include <stdexcept> void func() noexcept(false) { throw std::runtime_error("Error!"); } int main() { try { func(); } catch(const std::exception& ex) { std::cout << ex.what(); } }
Belangrijke kenmerken:
Is het toegestaan om uitzonderingen te gooien in een destructor?
Nee, het gooien van een uitzondering uit een destructor tijdens stack unwind leidt tot std::terminate(). Uitzonderingen in de destructor moeten binnen de destructor zelf worden opgevangen.
Wat gebeurt er als je een uitzondering gooit uit een noexcept-functie?
Er wordt std::terminate aangeroepen, het programma wordt abrupt afgesloten. noexcept is een strikte overeenkomst.
Kun je uitzonderingen op value vangen? Waarom is dit gevaarlijk?
Je kunt op value vangen, maar het object wordt gekopieerd (object slicing). Het wordt aanbevolen om const & te gebruiken.
Voorbeeldcode:
try { throw std::out_of_range("err"); } catch (const std::exception& e) { /* ... */ }
De code gooide uitzonderingen in destructors van bronnen; bij een abrupte afsluiting werd de stack niet correct uitgepakt, bronnen bleven lekken.
Voordelen:
Nadelen:
Kritieke methoden waren gemarkeerd met noexcept, destructors verwerkten alle uitzonderingen in hun eigen code. Catch werd met referentie toegepast, alle fouten werden gelogd.
Voordelen:
Nadelen: