C++异常处理笔记

异常基本语法:

第一种情况:

int xiangchu(int a, int b)
{
	if (b == 0)
	{
		throw b; //抛出异常
	}
	return a / b;
}

void test01()
{
//试着捕获异常
	try {
		xiangchu(10, 0);
	}
	catch (int) //异常根据类型匹配 
	{
		cout << "除数为0" << endl;
	}
}

void test02()
{
//试着捕获异常
	try {
		xiangchu(10, 0);
	}
	catch (int e) //异常根据类型匹配 
	{
		cout << "除数为"<< e << endl;
	}
}

第二种情况:

#include<iostream>
using namespace std;

int xiangchu(int a, int b)
{
	if (b == 0)
	{
		throw b; //抛出异常
	}
	return a / b;
}
void test01(int s,int d)
{
	xiangchu(s, d);
	
}
void test02()
{
	try{
	test01(10,0);
	}
	catch (int e)
	{
		cout << "除数为" << e << endl;
	}
}
int main()
{
	test02();
}

总结:

如果异常抛到顶层,还没有处理,这个时候程序就会挂掉(调用terminate())

C++的异常机制是跨函数的

C++异常是必须要处理的

栈解旋:

栈解旋定义:

当语句写入try中时,如果抛出了异常,那么栈区中的局部变量将被自动析构掉

#include<iostream>
using namespace std;
class Person
{
public:
	Person();
	~Person();
};
Person::Person()
{
	cout << "构造函数调用" << endl;
}
Person::~Person()
{
	cout << "析构函数调用" << endl;
}
int xiangchu(int a, int b)
{
	Person p1;
	if (b == 0)
	{
		throw b; //抛出异常
	}
	return a / b;
}
void test01()
{
	try {
		xiangchu(10, 0);
	}
	catch (int e)
	{
		cout << "捕获异常!" << endl;
	}
}
int main()
{
	test01();
}

异常接口声明:

void func() throw(int,float,char) //这个函数只能抛出int float char三种异常类型
{
}

void func2() throw() //这个函数不能抛出任何异常
{
}

void fun3() //这个函数可以抛出任何类型的异常
{
}


void test01()
{
try{
func3();
}
catch(...) //捕获所有异常
{
cout<<"未知类型异常!"<<endl;
}

异常类型:

#include<iostream>
using namespace std;
class Person
{
public:
	void what()
	{
		cout << "抛出异常!" << endl;
	}
};
void fun1()
{
	throw 1;
}
void fun2()
{
	throw "hellp";
}
void fun3()
{
	throw Person();
}
void test01()
{
	try {
		fun1();
	}
	catch (int e)
	{
		cout << "捕获异常" << endl;
	}
}
void test02()
{
	try {
		fun2();
	}
	catch (const char* e)
	{
		cout << "捕获异常"  << endl;
	}
}
void test03()
{
	try {
		fun3();
	}
	catch (Person p1)
	{
		p1.what();
	}
}
int main()
{
	test01();
	test02();
	test03();
	return 0;
}

异常对象的生命周期:

普通元素:异常对象catch处理完之后就析构

引用:不用调用拷贝构造,异常对象catch处理完之后就析构

指针:需要开辟新的内存空间,调用异常后delete指针

如何编写自己的异常类:

1、继承C++标准异常类,毕竟C++可以抛出任何类型的异常,不继承自标准异常,可能会导致程序混乱。

2、继承了标准异常类时,我们就需要重载父类的what函数和虚析构函数。

3、要根据你在类中添加的成员考虑是否提供自己的复制构造函数。

测试:

基于<stdexcept>下的<out_of_range>编写自己的异常类

#include<iostream>
#include<stdexcept>
using namespace std;

class Person
{
public:
	int Page;
public:
	Person()
	{
		Page = 0;
	}
	void setAge(int age)
	{
		if (age < 0||  age > 100)
		{
			throw out_of_range("年龄不正确");
			/*throw exception("年龄不正确");*/
		}
		this->Page = age;
	}
};
void test01()
{
	Person p;
	try {
		p.setAge(1000);
	}
	catch (out_of_range e) 
	{
		cout << e.what();
	}
	/*catch (exception e)
	{
		cout<<e.what();
	}*/
}
class MyOutofrange : public exception
{
public:
	MyOutofrange(const char * error)
	{
		Error = new char[strlen(error)+1];
		strcpy(Error, error);
	}
	~MyOutofrange()
	{
		if (Error != NULL)
		{
			delete[] Error;
		}
	}
	virtual const char* what() const {
		return Error;
	}
public:
	char* Error;
};
void fun2()
{
	throw MyOutofrange("我的异常");
}
void test02()
{
	try {
		fun2();
	}
	catch (exception& e) //需要引用区接是因为没有重写拷贝构造
	{
		cout << e.what() << endl;
	}
}
int main()
{
	test01();
	test02();
}

建议写自己的异常类的时候都要重载一个等号和重写拷贝构造

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值