c++ 11 异常处理 北京大学C++程序设计实习公开课
2015-10-23 09:20
197 查看
需要进行异常处理的情况:
异常处理的思路:
1、把异常和函数的接口分开,并且能够区分不同的异常
2、在函数体外捕获所发生的异常,并提供更多的异常信息
异常处理:
1、在函数内发生异常,可以在函数内自己处理
2、在函数内发生的异常,可以在函数外,让调用者处理。
3、抛出异常,其实就是抛出对象,所以,可以自己定义类对象来进行抛出。
C++ 进行异常处理就是使用try {} catch {}
然后用catch块捕获异常,输出异常的信息,catch 块的执行是自上而下的,catch(...)是上面的catch块没有一个匹配的,就执行catch(...)
异常的再抛出
如果一个函数在执行的过程中,抛出的异常在本函数内就被catch块捕获并处理了,那么该异常就不会抛给这个函数的调用者(也称"上一层函数");如果异常在本函数中没被处理,就会被抛给上一层的函数。
C++标准异常类
bad_cast:
在用dynamic_cast 进行从多态基类对象(或 引用),到派生类的引用的强制类型转换时,如果转换是不安全的,则会抛出异常。
bad_alloc:
在用new 运算符进行动态内存分配时,如果没有足够多的内存,则会引发此异常。
out_of_range
用vector或string的at成员函数根据下标访问元素时,如果下标越界,就会抛出此异常。例如:
异常处理的思路:
1、把异常和函数的接口分开,并且能够区分不同的异常
2、在函数体外捕获所发生的异常,并提供更多的异常信息
异常处理:
1、在函数内发生异常,可以在函数内自己处理
2、在函数内发生的异常,可以在函数外,让调用者处理。
3、抛出异常,其实就是抛出对象,所以,可以自己定义类对象来进行抛出。
C++ 进行异常处理就是使用try {} catch {}
int main { double m,n; cin>>m>>n; try { if (n == 0) throw -1; //抛出int类型异常 else if (m == 0) throw -1.0; //抛出double类型异常 else cout<<m/n<<endl; cout<<"after dividing"<<endl; } catch(double d) { cout<<"catch(double)"<<d<<endl; } catch(int e) { cout<<"catch(int)"<<e<<endl; } catch(...) { cout<<"catch(...)"<<endl; } cout<< "finished"<<endl; }解释:在可能发生异常现象的地方,加try {} 。如果发生异常,则用throw 抛出异常。
然后用catch块捕获异常,输出异常的信息,catch 块的执行是自上而下的,catch(...)是上面的catch块没有一个匹配的,就执行catch(...)
异常的再抛出
如果一个函数在执行的过程中,抛出的异常在本函数内就被catch块捕获并处理了,那么该异常就不会抛给这个函数的调用者(也称"上一层函数");如果异常在本函数中没被处理,就会被抛给上一层的函数。
#include <vector> #include <iostream> #include <time.h> #include"Exception.h" using namespace std; //异常抛出让调用者进行处理 double Devide(double x,double y) { if(y == 0) throw CException("devided by zero"); cout<<"in Devide"<<endl; return x/y; } //函数抛出的异常,函数内自己处理 int CountTax(int salary) { try { if(salary < 0) throw -1; cout<<"counting tax"<<endl; } catch (int){ cout<<"salary < 0" <<endl; } cout<<"tax counted" <<endl; return salary*0.15; } int main() { double f = 1.2; try { CountTax(-1); f = Devide(3,0); cout<< "end of try block"<<endl; } catch (CException e) { cout<<e.getmsg()<<endl; } cout<<"f = "<<f<<endl; cout<<"finished"<<endl; return 0; }
C++标准异常类
bad_cast:
在用dynamic_cast 进行从多态基类对象(或 引用),到派生类的引用的强制类型转换时,如果转换是不安全的,则会抛出异常。
#include <iostream> //include 这个头文件才能进行异常处理 #include<stdexcept> using namespace std; //虚基类 class Base { virtual void func() {} }; class Derived:public Base { public: void Print() {} }; //b是基类的对象,b可以指向基类对象,也可以指向派生类对象 //如果b指向派生类对象,那么将基类转为派生类是安全的 //如果b是基类对象,那么将基类转换为派生类对象是不安全的 void PrintObj(Base& b) { try { Derived& rd = dynamic_cast<Derived&> (b); //此转换若不安全,则会抛出bad_cast异常 rd.Print(); } catch(bad_cast & e) { cerr<<e.what()<<endl; } } int main() { Base b; PrintObj(b); return 0; }
bad_alloc:
在用new 运算符进行动态内存分配时,如果没有足够多的内存,则会引发此异常。
#include<stdexcept> using namespace std; int main() { try { char* p = new char[0x7fffffff];//无法分配这么多空间,会抛出异常 } catch(bad_alloc& e) { cerr<<e.what()<<endl; } return 0; }
out_of_range
用vector或string的at成员函数根据下标访问元素时,如果下标越界,就会抛出此异常。例如:
#include <iostream> #include<vector> #include<string> //include 这个头文件才能进行异常处理 #include<stdexcept> using namespace std; int main() { vector<int> v(10); try { v.at(100) = 100; //抛出out_of_range 异常 } catch (out_of_range& e) { cerr <<e.what()<<endl; } return 0; }
相关文章推荐
- 【第7周 项目4 - 队列数组】
- C++的引用
- 【第7周 项目3 - 负数把正数赶出队列】
- 高精度除法与求余C++版和java版
- 1021. 个位数统计 (15)
- 第6周项目4 数制转换
- Leetcode Rotate Image
- 【C/C++学院】0819-/类的成员函数与const-mutable /构造与析构/拷贝构造deletedefault以及深浅拷贝/静态成员函数成员变量类在内存的存储默认参数/友元类以及友元函数
- Leetcode NO.246 Strobogrammatic Number
- 第6周项目3 括号的匹配
- C++异常处理
- Leetcode NO.252 Meeting Rooms
- Leetcode NO.243 Shortest Word Distance
- c语言 -> 条件控制 / if / switch / for
- C++ 之main 函数的返回值
- C语言 - > 算数运算 / 赋值运算 / 关系运算 / 逻辑运算 / 三目运算
- C++拷贝构造函数详解
- leetcode笔记:Binary Tree Zigzag Level Order Traversal
- C++类的成员函数使用的一些小总结
- C语言的简单函数定义与调用