C++标准库异常类继承层次中的根类为exception,其定义在exception头文件中,它是C++标准库全部函数抛出异常的基类,exception的接口定义以下:ios
namespace std { class exception { public: exception() throw(); //不抛出任何异常 exception(const exception& e) throw(); exception& operator= (const exception& e) throw(); virtual ~exception() throw)(); virtual const char* what() const throw(); //返回异常的描述信息 }; }
先来看一下 exception 类的直接派生类:c++
异常名称 | 说 明 |
---|---|
logic_error | 逻辑错误。 |
runtime_error | 运行时错误。 |
bad_alloc | 使用 new 或 new[ ] 分配内存失败时抛出的异常。 |
bad_typeid | 使用 typeid 操做一个 NULL 指针,并且该指针是带有虚函数的类,这时抛出 bad_typeid 异常。 |
bad_cast | 使用 dynamic_cast 转换失败时抛出的异常。 |
ios_base::failure | io 过程当中出现的异常。 |
bad_exception | 这是个特殊的异常,若是函数的异常列表里声明了 bad_exception 异常,当函数内部抛出了异常列表中没有的异常时,若是调用的 unexpected() 函数中抛出了异常,不论什么类型,都会被替换为 bad_exception 类型。 |
logic_error 的派生类:dom
异常名称 | 说 明 |
---|---|
length_error | 试图生成一个超出该类型最大长度的对象时抛出该异常,例如 vector 的 resize 操做。 |
domain_error | 参数的值域错误,主要用在数学函数中,例如使用一个负值调用只能操做非负数的函数。 |
out_of_range | 超出有效范围。 |
invalid_argument | 参数不合适。在标准库中,当利用string对象构造 bitset 时,而 string 中的字符不是 0 或1 的时候,抛出该异常。 |
runtime_error 的派生类:函数
异常名称 | 说 明 |
---|---|
range_error | 计算结果超出了有意义的值域范围。 |
overflow_error | 算术计算上溢。 |
underflow_error | 算术计算下溢。 |
原则:建议继承标准异常类,并重载父类的what函数和析构函数this
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include<stdexcept> using namespace std; class Person { public: Person() { mAge = 0; } void setAge(int age) { if (age < 0 || age > 100) { throw out_of_range("年龄应该在0-100之间!"); } this->mAge = age; } public: int mAge; }; //test01()使用标准库的异常类,下面的exception能够换为out_of_range void test01() { Person p; try { p.setAge(1000); } catch (exception e) { cout << e.what() << endl; } } //本身写个异常类,重载父类的what函数和析构函数 class MyOutOfRange : public exception { public: MyOutOfRange(const char* error) { pError = new char[strlen(error) + 1]; strcpy(pError, error); } ~MyOutOfRange() { if (pError != NULL) { delete[] pError; } } virtual const char* what() const { return pError; }; public: char* pError; }; void fun02() { throw MyOutOfRange("我本身的out_of_range!"); } void test02() { try { fun02(); } catch (exception& e) { cout << e.what() << endl; } } int main(void) { test01();//结果:年龄应该在0-100之间! //test02();//结果:我本身的out_of_range! return 0; }
异常尽可能抛个类对象(基类),不要再用 -1 或 char* 。spa
#define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; //异常基类 class BaseMyException { public: virtual void what() = 0; virtual ~BaseMyException() {} }; class TargetSpaceNullException : public BaseMyException { public: virtual void what() { cout << "目标空间空!" << endl; } ~TargetSpaceNullException() {} }; class SourceSpaceNullException : public BaseMyException { public: virtual void what() { cout << "源空间为空!" << endl; } ~SourceSpaceNullException() {} }; void copy_str(char* taget, char* source) { if (taget == NULL) { throw TargetSpaceNullException(); } if (source == NULL) { throw SourceSpaceNullException(); } //int len = strlen(source) + 1; while (*source != '\0') { *taget = *source; taget++; source++; } } int main(void) { const char* source = "abcdefg"; char buf[1024] = { 0 }; try { copy_str(buf, NULL); } catch (BaseMyException& ex) { ex.what(); } cout << buf << endl; return 0; } //结果:源空间为空!