CS253: Software Development with C++

Spring 2018

Exception Handling

See this page as a slide show

CS253 Exception Handling

Normal Operation

#include "Loud.h"

Loud a('a');

void foo() {
    Loud b('b');
    Loud c('c');
}

int main() {
    Loud d('d');
    foo();
    Loud e('e');
    return 0;
}
Loud::Loud() [c='a']
Loud::Loud() [c='d']
Loud::Loud() [c='b']
Loud::Loud() [c='c']
Loud::~Loud() [c='c']
Loud::~Loud() [c='b']
Loud::Loud() [c='e']
Loud::~Loud() [c='e']
Loud::~Loud() [c='d']
Loud::~Loud() [c='a']

throw without catch

#include "Loud.h"

Loud a('a');

void foo() {
    Loud b('b');
    throw 42;
    Loud c('c');
}

int main() {
    Loud d('d');
    foo();
    Loud e('e');
    return 0;
}
Loud::Loud() [c='a']
Loud::Loud() [c='d']
Loud::Loud() [c='b']
terminate called after throwing an instance of 'int'
SIGABRT: Aborted

You can throw anything—doesn’t have to be a special type or object.

try #1

#include "Loud.h"

Loud a('a');

void foo() {
    Loud b('b');
    throw "oops!";
    Loud c('c');
}

int main() {
    Loud d('d');
    try {
        foo();
    }
    catch (const char *error) {
        cout << "Caught: " << error << "\n";
    }

    Loud e('e');
    return 0;
}
Loud::Loud() [c='a']
Loud::Loud() [c='d']
Loud::Loud() [c='b']
Loud::~Loud() [c='b']
Caught: oops!
Loud::Loud() [c='e']
Loud::~Loud() [c='e']
Loud::~Loud() [c='d']
Loud::~Loud() [c='a']

try #2

#include "Loud.h"

Loud a('a');

void foo() {
    Loud b('b');
    throw "oops!";
    Loud c('c');
}

void bar() {
    Loud d('d');
    foo();
}

int main() {
    Loud e('e');
    try {
        bar();
    }
    catch (const char *error) {
        cout << "Caught: “" << error << "”\n";
    }

    Loud f('f');
    return 0;
}
Loud::Loud() [c='a']
Loud::Loud() [c='e']
Loud::Loud() [c='d']
Loud::Loud() [c='b']
Loud::~Loud() [c='b']
Loud::~Loud() [c='d']
Caught: “oops!”
Loud::Loud() [c='f']
Loud::~Loud() [c='f']
Loud::~Loud() [c='e']
Loud::~Loud() [c='a']

catch #1

try {
    throw "oops!";
}

catch (int i) {
    cout << "int " << i << "\n";
}

catch (const char *error) {
    cout << "C string: " << error << "\n";
}

catch (...) {
    cout << "something\n";
}
C string: oops!

catch #2

try {
    throw 42;
}

catch (short s) {
    cout << "Got a short: " << s << "\n";
}

catch (long l) {
    cout << "Got a long: " << l << "\n";
}
terminate called after throwing an instance of 'int'
SIGABRT: Aborted

The type must match. No conversions!

catch #3

// logic_error is-a exception
// runtime_error is-a exception
// overflow_error is-a runtime_error

try {
    overflow_error oops("OVERFLOW!");
    throw oops;
}
catch (const logic_error &e) {
    cout << "logic_error: " << e.what() << '\n';
}
catch (const runtime_error &e) {
    cout << "runtime_error: " << e.what() << '\n';
}
catch (const exception &e) {
    cout << "exception: " << e.what() << '\n';
}
runtime_error: OVERFLOW!

catch #4

// logic_error is-a exception
// runtime_error is-a exception
// overflow_error is-a runtime_error

try {
    overflow_error oops("OVERFLOW!");
    throw oops;
}
catch (const logic_error &e) {
    cout << "logic_error: " << e.what() << '\n';
}
catch (const exception &e) {
    cout << "exception: " << e.what() << '\n';
}
exception: OVERFLOW!

No conversions, but is-a is good enough.

re-throw

void foo() {
    throw string("Division by zero");
}

void bar() {
    try {
        foo();
    }
    catch (string msg) {
        if (msg == "Out of memory")  // I’ve got this!
            /* get more memory */;
        else
            throw;      // Throw up hands in despair.
    }
}

int main() {
    try {
        bar();
    }
    catch (string problem) {
        cout << "Problem in bar: " << problem << '\n';
    }

    return 0;
}
Problem in bar: Division by zero

User: Guest

Check: HTML CSS
Edit History Source

Modified: 2018-04-24T16:51

Apply to CSU | Contact CSU | Disclaimer | Equal Opportunity
Colorado State University, Fort Collins, CO 80523 USA
© 2018 Colorado State University
CS Building