C++ 异常机制(下)

C++ 异常机制(上)

八、C++标准异常类

C++标准库异常类继承层次中的根类为exception,其定义在exception头文件中,它是C++标准库所有函数抛出异常的基类,exception的接口定义如下:

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 类的直接派生类:

异常名称说 明
logic_error逻辑错误。
runtime_error运行时错误。
bad_alloc使用 new 或 new[ ] 分配内存失败时抛出的异常。
bad_typeid使用 typeid 操作一个 NULL 指针,而且该指针是带有虚函数的类,这时抛出 bad_typeid 异常。
bad_cast使用 dynamic_cast 转换失败时抛出的异常。
ios_base::failureio 过程中出现的异常。
bad_exception这是个特殊的异常,如果函数的异常列表里声明了 bad_exception 异常,当函数内部抛出了异常列表中没有的异常时,如果调用的 unexpected() 函数中抛出了异常,不论什么类型,都会被替换为 bad_exception 类型。

logic_error 的派生类:

异常名称说 明
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函数和析构函数

#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* 。

#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;
}
//结果:源空间为空!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值