帐前卒专栏

Without software, we are nothing.

try...catch...exception in C++

if you will throw something, you should catch it as the same type. like following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
int main(){
    try{
        throw 20;
    }catch(int i){
        cout << "Exception Num is NO."<<i<<endl;
    }
    try{
        throw 'X';
    }catch(char c){
        cout << "this exception is a char:"<<c<<endl;
    }

    try{
        throw "abc";
    }catch(const char * e){
        cout << "this is string exception:"<<e<<endl;
    }

    try{
        int *d = new int(65);
        throw d;
    }catch(const int * e){
        cout << "this is int point exception:"<<*e<<endl;
    }
    /* ok, catch will handle everything, if you throw correct type.*/
}

and if you want create classes for exceptions. You should add #include<exception> and inherit exception class, and then override the function ”what”.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include<iostream>
#include<exception>
using namespace std;

/// this exception class is from #include<exception>
/// you should override the function what() to generate your exception string
class MyException: public exception{
    virtual const char* what() const throw(){
        return "myExceptions!!!!!!!";

    }

};

class SubException: public MyException{
    virtual const char* what()const throw(){
        return "sub exception !!!!!!";
    }

};

int main(){
    try{
        throw MyException();
    }catch(exception& e){
        cout << e.what()<<endl;

    }
    try{
        throw SubException();
    }catch(bad_alloc&){
        // this will not occur, just test this type.
        // if it is occured, your computer will be locked.
        cout << "nothing"<<endl;
    }catch(exception& e){
        cout << e.what()<<endl;

    }

}

There are some standard exceptions in exception.h. These exceptions are:

bad_alloc

A bad_alloc is thrown by new if an allocation failure occurs.

bad_cast

A bad_cast is thrown by dynamic_cast when it fails with a referenced type.

bad_exception

A bad_exception is thrown when an exception type doesn’t match any catch

bad_typeid

A bad_typeid is thrown by typeid

ios_base::failure

An ios_base::failure is thrown by functions in the iostream library.

in #include<stdexecpt> can use these exception: class logic_error; // : public exception class domain_error; // : public logic_error class invalid_argument; // : public logic_error class length_error; // : public logic_error class out_of_range; // : public logic_error class runtime_error; // : public exception class range_error; // : public runtime_error class overflow_error; // : public runtime_error class underflow_error; // : public runtime_error

If you don’t know which kind of exception will occur. you should use catch(…)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
try{
        srand(time(NULL));
        int i = rand()%4;

        switch(i){
            case 0:
                throw; // terminate called without an active exception
                       // Aborted, ... will not catch it.
                break;
            case 1:
                throw 'x';
                break;
            case 2:
                throw 50;
                break;
            case 3:
                throw "my string";
                break;
            default:
                break;

        }

    }catch(...){
        cout << "I don't know which exception will occur!"<<endl;
    }

But when i == 0, the program will execute throw;, and it will exit and print:

terminate called without an active exception Aborted

You should specify something to throw. throw; is only be used within catch clauses.

1
2
3
4
5
6
7
8
9
try{
        try{
            throw 2;
        }catch(int i){
            throw; // here I use it again!
        }
    }catch(...){
        cout << "re-throw it!!!!"<<endl;
    }

you can declare your functions using throw(). But it is just declare!  you can throw everything! But you declare it will throw bad_exception, and use set_unexpected(), it will process some unexpected exceptions.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void foo() throw(int,bad_exception){

    throw "abc";
}
void myunexpected(){
    cout << "I get unexpected exceptions!"<<endl;
    throw;
}

// in main

    set_unexpected(myunexpected);
    try{
        foo();
    }catch(int){
        cout << "catch a integer"<<endl;
    }catch(bad_exception&){
        cout << "bad_exception"<<endl;
    }
    // you can use catch(...)

output is

I get unexpected exceptions! bad_exception

If the program or your function can not process some kind of situation. you should throw something out.  Sometime, someone argued that it will reduce the usability. But If you don’t stop the processing(program or function), it will create a disaster.  Remember, by all means, throw it! But should we catch those exceptions and how we catch those? e….as your wish. Some bug will not appear, if you use not appropriate catch and process those exceptions in unsuitable way. If your program have some bug, and it is difficult to find, please delete all catches!

In some languages which have finally clauses. But in c++, it dose not have finally clauses.

Comments