用try、catch处理异常
#include <iostream>
using namespace std;
int main() {
double m, n;
cin >> m >> n;
try {
cout << "before dividing." << endl;
if(n == 0)
throw -1; // 抛出int类型异常
else
cout << m / n << endl;
cout << "after dividing." << endl;
} catch (double d) {
cout << "catch(double)" << endl;
} catch(int e) {
cout << "catch(int)" << endl;
}
cout << "finished." << endl;
}
/************* 输入
9 6
************** 输出
before dividing.
1.5
after dividing.
finished.
**************/
- 在
try
块中一旦抛出异常,下面的语句不再执行 如果
try
中没有抛出异常,则一个catch
也不会执行- 就算抛出异常,但是
catch
捕获的类型不匹配,也不会执行 -
… 捕获任何异常
#include <iostream>
using namespace std;
int main() {
double m, n;
cin >> m >> n;
try {
cout << "before dividing." << endl;
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(...) { // 捕获任何类型异常
cout << "catch(...)" << endl;
}
cout << "finished." << endl;
}
/************* 输入
9 0
0 6
************** 输出
before dividing.
catch(...)
finished.
before dividing.
catch(double)-1
finished
**************/
异常再抛出
如果一个函数在执行的过程中,抛出的异常在本函数内就被
catch
块捕获并处理了,那么该异常就不会抛给这个函数的调用者(也称“上一层的函数” );如果异常在本函数中没被处理,就会被抛给上一层的函数#include <iostream>
#include <string>
using namespace std;
class CException {
public:
string msg;
CException(string s):msg(s){}
};
double Divide(double x, double y) {
if(y == 0)
throw CException("divided by zero");
cout << "in Divide" << endl;
return x / y;
}
int CountTax(int salary) {
try {
if(salart < 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 = Divide(3, 0); // 没有修改f的值
cout << "end of try block" << endl;
}
catch(CException e) {
cout << e.msg << endl;
}
cout << "f=" << f << endl;
cout << "finished" << endl;
return 0;
}
/************** 输出
salary < 0
tax counted
diveded by zero
f=1.2
finished
**************/
C++标准异常类
bad_cast
在用
dynamic_cast
进行从多态基类对象(或引用) ,到派生类的引用的强制类型转换时,如果转换是不安全的,则会抛出此异常#include <iostream>
#include <stdexcept>
#include <typeinfo>
using namespace std;
class Base
{
virtual void func(){}
};
class Derived : public Base
{
public:
void Print() { }
};
void PrintObj(Base & b) {
try {
Derived & rd = dynamic_cast<Derived &>(b);
// 此转换若不安全,会抛出bad_cast异常
rd.Print();
} catch(bad_cast& e) {
cout << e.what() << endl;
}
}
int main() {
Base b;
PrintObj(b);
reutnr 0;
}
// 输出 Bad dynamic_cast
bad_alloc
在用
new
运算符进行动态内存分配时,如果没有足够的内存,则会引发此异常#include <iostream>
#include <stdexcept>
using namespace std;
int main() {
try {
char * p = new char[0x7ffffff]; // 无法分配这么多空间,会抛出异常
} catch (bad_alloc& e) {
cout << e.what() << endl;
}
return 0;
}
// 输出 bad allocation
- 就算抛出异常,但是
out_of_range
用 vector
或 string
的 at
成员函数根据下标访问元素时,如果下标越界,就会抛出此异常
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>
int main() {
vector<int> v(10);
try {
v.at(100) = 100; // 抛出异常
} catch(out_of_range& e) {
cerr << e.what() << endl;
}
string s = "Hello";
try {
char c = s.at(100); // 抛出异常
} catch(out_of_range& e) {
cerr << e.what() << endl;
}
return 0;
}
/***************** 输出
invalid vector<T< subscript
invalid string position
******************/