正在加载……
专注、离线、切勿分心
通过继承和重载exeception类定义新的异常
exeception类有一个虚函数
virtual const char* what() const;  //c++11之后不再用了
virtual const char* what() const noexcept;
const 后面跟throw() 不是函数,这个东西叫异常规格说明,表示 what 函数可以抛出异常的类型,类型说明放到 () 里,这里面没有类型,就是声明这个函数不抛出异常,通常函数不写后面的就表示函数可以抛出任何类型的异常。
异常规格说明:
1、异常规格说明的目的是为了让函数使用者知道该函数可能抛出的异常有哪些。 可以在函数的声明中列出这个函数可能抛掷的所有异常类型。例如:void fun() throw(ABCD);
2、若无异常接口声明,则此函数可以抛掷任何类型的异常。
3、不抛掷任何类型异常的函数声明如下:void fun() throw();
//继承exeception类实现自己的异常
#include<iostream>
#include<exception>
using namespace std;
class MyException:public exception
{
        public:
                const char* what()const throw()  
//函数后面必须跟throw(),括号里面不能有任务参数,表示不抛出任务异常
//因为这个已经是一个异常处理信息了,不能再抛异常。
                {
                        return "MyException";
                }
};
int main()
{
        try
        {
                throw MyException();
        }
        catch(MyException& e)    //传引用,防止调用拷贝构造函数
        {
                cout<<"this is MyException"<<endl;
                cout<<e.what()<<endl;
        }
}



//自己实现异常
#include<iostream>
#include<string>
using namespace std;
class exA
{
        public:
                exA(string strA):_strA(strA){ cout<<"exA()"<<endl; }
                ~exA(){ cout<<"~exA()"<<endl; }
                virtual const char* what()const throw()
                {
                        return _strA.c_str();
                }
        private:
                string _strA;
};
class exB : public exA
{
        public:
                exB(string strB):_strB(strB),exA("exA"){ cout<<"exB()"<<endl; }
                ~exB(){ cout<<"~exB()"<<endl; }
                const char* what()const throw()
                {
                        return _strB.c_str();
                }
        private:
                string _strB;
};
void fun(int n) throw(int,exA,exB)    //只能抛出int,exA,exB类型错误
{
        if(1==n){throw 1;}
        else if(2==n){throw exA("this is exA");}
        else if(3==n){ throw exB("this is exB");}
        else {throw 2.2;}
}

int main()
{
        try
        {
        //      fun(1);
        //      fun(2);
                fun(3);       //这里最终调动的是exA
                //因为在抛出异常对象的时候又建立了一个exA对象
                //要想执行异常exB,就要注释掉catch(exA& b)
                //不注释掉最后结果就是程序最后面一个
        //      fun(4);       //运行出现下列错误
                //terminate called after throwing an instance of 'double'
                //Aborted (core dumped)
        }
        catch(int a)
        {
                cout<<"throw int"<<endl;
        }
//      catch(exA& b)
//      {
//              cout<<b.what()<<endl;
//              cout<<"throw exA"<<endl;
//      }
        catch(exB& c)
        {
                cout<<c.what()<<endl;
                cout<<"throw exB"<<endl;
        }
        catch(...)
        {
                cout<<"oth exception"<<endl;
        }
        return 0;
}


//throw int

//exA()
//throw exA
//~exA()

//exA()
//this is exA
//throw exA
//~exA()


//exA()
//exB()
//this is exB
//throw exB
//~exB()
//~exA()

//exA()
//exB()
//this is exB
//throw exB
//~exB()
//~exA()


#include<iostream>
#include<exception>
using namespace std;
class myException:public exception
{
        public:
                myException(const char* str):_str(const_cast<char*>(str)) { }
                virtual ~myException()throw() { cout<<"~myException()"<<endl; }
                //析构函数不能抛出异常,不许加异常规格说明throw()
                const char* what()
                {
                        return _str;
                }
        private:
                char* _str;
};
int func(int a ,int b)throw(myException)  //函数可能抛出myException异常
{
        if(0==b)
        {
                throw *(new myException("除数不能为0"));    //两种都可以
        }
        return a/b;
}
int main()
{
        int a = 5,b = 0;
        int res;
        try
        {
                res = func(a,b);
        }
        catch(myException& e)
        {
                cout<<e.what()<<endl;
        //      delete &e;
        // 已经释放了,不用再释放了
        }
        cout<<res<<endl;
        return 0;
}
posted on 2018-07-26 08:56  正在加载……  阅读(2660)  评论(0编辑  收藏  举报