throw 表达式;
该语句拋出一个异常。异常是一个表达式,其值的类型可以是基本类型,也可以是类。
try {
语句组
}
catch(异常类型) {
异常处理代码
}
...
catch(异常类型) {
异常处理代码
}
{}中的内容称作“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
cout << m / n << endl;
cout << "after dividing." << endl;
}
catch(double d) {
cout << "catch(double) " << d << endl;
}
catch(int e) {
cout << "catch(int) " << e << endl;
}
cout << "finished" << endl;
return 0;
}
程序的运行结果如下:catch(int e)块执行,该 catch 块执行完毕后,程序继续往后执行,直到正常结束。catch(int e),改为catch(char e),当输入的 n 为 0 时,拋出的整型异常就没有 catch 块能捕获,这个异常也就得不到处理,那么程序就会立即中止,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; //抛出整型异常
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;
return 0;
}
程序的运行结果如下:catchy(...)捕获。catch (double)和catch(...)都能匹配该异常,但是catch(double)是第一个能匹配的 catch 块,因此会执行它,而不会执行catch(...)块。catch(...)能匹配任何类型的异常,它后面的 catch 块实际上就不起作用,因此不要将它写在其他 catch 块前面。
#include <iostream>
#include <string>
using namespace std;
class CException
{
public:
string msg;
CException(string s) : msg(s) {}
};
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.msg << endl;
}
cout << "f = " << f << endl;
cout << "finished" << endl;
return 0;
}
程序的输出结果如下:f = Devide(3, 0);。
#include <iostream>
#include <string>
using namespace std;
int CountTax(int salary)
{
try {
if( salary < 0 )
throw string("zero salary");
cout << "counting tax" << endl;
}
catch (string s ) {
cout << "CountTax error : " << s << endl;
throw; //继续抛出捕获的异常
}
cout << "tax counted" << endl;
return salary * 0.15;
}
int main()
{
double f = 1.2;
try {
CountTax(-1);
cout << "end of try block" << endl;
}
catch(string s) {
cout << s << endl;
}
cout << "finished" << endl;
return 0;
}
程序的输出结果如下:throw;没有指明拋出什么样的异常,因此拋出的就是 catch 块捕获到的异常,即 string("zero salary")。这个异常会被 main 函数中的 catch 块捕获。
void func() throw (int, double, A, B, C);
或void func() throw (int, double, A, B, C){...}
上面的写法表明 func 可能拋出 int 型、double 型以及 A、B、C 三种类型的异常。异常声明列表可以在函数声明时写,也可以在函数定义时写。如果两处都写,则两处应一致。void func() throw ();
则说明 func 函数不会拋出任何异常。
#include <iostream>
#include <stdexcept>
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) {
cerr << e.what() << endl;
}
}
int main()
{
Base b;
PrintObj(b);
return 0;
}
程序的输出结果如下:
#include <iostream>
#include <stdexcept>
using namespace std;
int main()
{
try {
char * p = new char[0x7fffffff]; //无法分配这么多空间,会抛出异常
}
catch (bad_alloc & e) {
cerr << e.what() << endl;
}
return 0;
}
程序的输出结果如下:
#include <iostream>
#include <stdexcept>
#include <vector>
#include <string>
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;
}
string s = "hello";
try {
char c = s.at(100); //拋出 out_of_range 异常
}
catch (out_of_range & e) {
cerr << e.what() << endl;
}
return 0;
}
程序的输出结果如下:v.at(100)换成v[100],将s.at(100)换成s[100],程序就不会引发异常(但可能导致程序崩溃)。因为 at 成员函数会检测下标越界并拋出异常,而 operator[] 则不会。operator [] 相比 at 的好处就是不用判断下标是否越界,因此执行速度更快。
版权说明:Copyright © 广州松河信息科技有限公司 2005-2025 版权所有 粤ICP备16019765号
广州松河信息科技有限公司 版权所有