C++ 异常处理
C++ 通过 try/catch 语句来做异常处理,以下介绍常用的几种异常捕获和处理方式。
1. C 风格字符串异常
#include <iostream>
using namespace std;
double div_except_str(int a, int b) {
if (b == 0) {
throw "divider is zero";
}
return a / b;
}
int main() {
try {
div_except_str(1, 0);
} catch (const char* except) {
cout << except << endl;
}
return 0;
}
输出:
divider is zero
上述程序通过 throw 一个字符串异常,通过 try catch 语句块捕获,捕获的异常信息类型必须为 const char*
的 c 风格字符串。
2. 自定义普通异常类
自定义一个接受两个 int 型的 ExceptA 类,并通过 msg 函数输出异常信息:
#include <iostream>
using namespace std;
class ExceptA {
public:
ExceptA(int v1, int v2) : a(v1), b(v2) {}
void msg() { cout << "ExceptA " << a << ", " << b << endl; }
private:
int a;
int b;
};
double div_except(int a, int b) {
if (b == 0) {
throw ExceptA(a, b);
}
return a / b;
}
int main() {
try {
div_except(1, 0);
} catch (ExceptA &except) {
except.msg();
}
return 0;
}
输出:
ExceptA 1, 0
程序通过在检测到异常的地方 thow 一个 ExceptA 对象,try catch 捕获 ExeceptA 的引用,注意这里必须是引用类型。虽然 catch 的对象是 throw 对象的复制,这里依然使用引用的原因是可以支持同一个基类的多态。
3. 自定义异常类多态情形
一个申明抛出异常类型为基类的函数,可以抛出所有的子类异常,并被捕获。先定义异常类以及子类:
class ExceptBase {
public:
ExceptBase(int v1, int v2) : a(v1), b(v2) {}
virtual void msg() const { cout << "ExceptBase " << a << ", " << b << endl; }
protected:
int a;
int b;
};
class ExceptA : public ExceptBase {
public:
ExceptA(int v1, int v2) : ExceptBase(v1, v2) {};
virtual void msg() const { cout << "ExceptA " << a << ", " << b << endl; }
};
class ExceptASub : public ExceptA {
public:
ExceptASub(int v1, int v2) : ExceptA(v1, v2) {};
virtual void msg() const { cout << "ExceptASub " << a << ", " << b << endl; }
};
ExceptA 继承自 ExceptBase,ExceptASub 继承自 ExeceptA。msg 函数用于输出异常信息,定义为 virtual 虚函数允许子类重写。定义一个抛出基类类型异常的测试函数:
double test_except(int a, int b) throw (ExceptBase) {
if (b == 0) {
throw ExceptASub(a, b);
}
if (a == 0) {
throw ExceptA(a, b);
}
throw ExceptBase(a, b);
}
函数在不同的参数情况下,抛出不同的异常类型。对应的 try catch 语句:
try {
test_except(1, 0);
// test_except(0, 1);
// test_except(1, 1);
} catch (const ExceptASub &except) {
except.msg();
} catch (const ExceptA &except) {
except.msg();
} catch (const ExceptBase &except) {
except.msg();
}
必须从最外一层的子类开始匹配捕获。
C++ 默认的异常类
通过 exception 头文件包含基础的异常类型 exception,exception 提供 what 的虚方法返回 C 风格的字符串异常信息 const char *,子类可重写该方法。
class MyException : exception {
public:
virtual const char *what() { return "MyException"; };
}
try {
...
} catch(const MyException & e) {
cout << e.what() << endl;
...
}
c++ stdexcept 头文件中过定义了两个继承自 exception 的异常类:logic_error 和 runtime_error。两者均为 exception 的公有继承,并且提供一些更具体的子类类型异常。
logic_error:
- domain_error: 定义域错误
- invalid_argument:无效参数
- length_error:长度错误
runtime_error:
- range_error
- overflow_error
- underflow_error
0 条评论