C++ exception handling

Vaak gebruiken we de return-waarde van een functie om aan te geven of de functie succesvol werd uitgevoerd, bijvoorbeeld

Op de plaats van de aanroep wordt dan de fout afgehandeld of soms wordt de fout doorgegeven naar het niveau daarboven via weer een return-waarde.

Dat kan zo een aantal niveaus doorgaan en vereist een nauwkeurige administratie om ervoor te zorgen dat je uiteindelijk nog weet wat er op welke plaats fout ging en hoe je dat het beste kunt oplossen.

Exception handling in C++ is een mechanisme om fouten of gebeurtenissen af te handelen op de plaats waar ze het beste afgehandeld kunnen worden. Exceptions gaan dan ook buiten de normale programma-flow om.

Het idee is dat je op de plaats waar een situatie optreedt die speciale aandacht vereist (meestal een fout) een exception opgooit. Die exception reist dan langs een aantal zogenaamde 'exception handlers' die je van tevoren hebt klaargezet. Een exception handler is een stukje programma dat uitgevoerd wordt wanneer er een bepaald type exception langs komt. Hierin kan bijvoorbeeld de fout afgehandeld of opgelost worden of een nieuwe poging gedaan worden.

Zo lang de exception die je hebt opgegooid geen exception handler tegenkomt die op die specifieke exception staat te wachten reist de exception verder tot er een handler reageert of tot hij bovenaan de exception tree is.

In het catch-blok wordt de fout afgehandeld.

Exceptions zijn niet altijd nuttig of nodig. Wanneer gebruik je ze ?

Execption type

Bij het omhoog-gooien van een fout met throw geef je aan om wat voor fout het gaat door een variabele of constante van een bepaald type te 'throwen'. Dat type mag een int of long zijn of zelfs een object.

Standard exceptions

Er zijn enkele voorgedefinieerde exceptions zoals bad_alloc en standard library exceptions zoals out_of_range. Om de laatste te kunnen gebruiken moet je de header stdexcept gebruiken bij het compileren:
#include <stdexcept>

Voordelen van exceptions boven de traditionele manier

Een groot voordeel is dat destructoren van objecten die je op allerlei niveaus hebt gemaakt netjes worden aangeroepen omdat je telkens netjes een blok (scope) verlaat. Bij een longjmp of exit is dat niet zo.

Een voordeel boven het werken met return-waarden is dat het nogal wat administratie kan uitsparen. Bovendien wordt een bepaalde fout automatisch op het juiste niveau afgehandeld.

- rethrow - derive van exception class - catch(...)

Heeft het ook nadelen ?

Soms meer runtime overhead ? Dat zal meestal wel meevallen. Conventionele foutafhandeling is ook niet gratis.

Voorbeeld: exception