62.C++异常

异常
try 试图执行 try{}中的内容
在可能出现异常的地方 抛出异常  throw
try下面 catch捕获异常 
catch( 捕获类型 )  …代表 所有其他类型
如果不想处理异常,继续向上抛出  throw
如果没有任何处理异常的地方,那么成员调用terminate函数,中断程序
自定义异常类 ,可以抛出自定义的对象  ,捕获自定义的异常
栈解旋
从try开始  到 throw 抛出异常之前  所有栈上的对象 都会被释放 这个过程称为栈解旋
栈上对象构造顺序与析构顺序相反

int A_MyDivide(int a, int b){
	if (b == 0){
		throw 0;
	}

	return a / b;
}

//B写的代码 B写代码比较粗心,忘记处理异常
int B_MyDivide(int a, int b){

	int ba = a;
	int bb = b;

	int ret = A_MyDivide(ba, bb) + 100;  //由于B没有处理异常,导致B结果运算错误

	return ret;
}

//C写的代码
int C_MyDivide(){

	int a = 10;
	int b = 0;

	int ret = 0;

//没有处理异常,程序直接中断执行
#if 1 
	ret = B_MyDivide(a, b);

//处理异常
#else 
	try{
		ret = B_MyDivide(a, b); //更严重的是,由于B没有继续抛出异常,导致C的代码没有办法捕获异常
	}
	catch (int e){
		cout << "C_MyDivide Call B_MyDivide 除数为:" << e << endl;
	}
#endif
	
	return ret;
}

int main(){

	C_MyDivide();

	system("pause");
	return EXIT_SUCCESS;
}

main.cpp

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

class myException //自定义异常类
{
public:
	void printError()
	{
		cout << "自定义的异常" << endl;
	}
};

class Person
{
public:
	Person()
	{
		cout << "Person构造" << endl;
	}
	~Person()
	{
		cout << "Person析构" << endl;
	}

};

int myDevide(int a, int b)
{
	if (b == 0)
	{
		//如果b是异常 抛出异常
		//return -1;

		//throw 1; 抛出int类型异常
		//throw 3.14; //抛出double类型异常  异常必须处理,如果不处理 就挂掉

		//throw 'a';

		//栈解旋
		//从try开始  到 throw 抛出异常之前  所有栈上的对象 都会被释放 这个过程称为栈解旋
		//构造和析构顺序相反
		Person p1;
		Person p2;


		throw myException(); //匿名对象
		/*输出
		Person构造
		Person构造
		Person析构
		Person析构
		*/

	}
	return a / b;
}



void test01()
{
	int a = 10;
	int b = 0;

	//int ret = myDevide(a, b); //早期如果返回-1 无法区分到底是结果还是异常

	//C++中异常处理

	try //试一试
	{
		myDevide(a, b);
	}
	catch (int) //捕获异常
	{
		cout << "int类型异常捕获" << endl;
	}
	catch (double)
	{
		//如果不想处理这个异常 ,可以继续向上抛出
		throw;
		cout << "double类型异常捕获" << endl;
	}
	catch (myException e)
	{
		e.printError();
	}
	catch (...)
	{
		cout << "其他类型异常捕获" << endl;
	}

}


int main(){

	try
	{
		test01();
	}
	catch (char) //如果异常都没有处理,那么成员terminate函数,使程序中断
	{
		cout << "main 函数中 double类型异常捕获" << endl;
	}
	catch (...)
	{
		cout << "main函数中 其他类型异常捕获" << endl;
	}


	system("pause");
	return EXIT_SUCCESS;
}

异常变量的生命周期

// 44.异常.cpp : 定义控制台应用程序的入口点。
//

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

class MyException
{
public:
	MyException()
	{
		cout << "MyException的默认构造" << endl;
	}
	MyException(const MyException & e)
	{
		cout << "MyException的拷贝构造" << endl;
	}

	~MyException()
	{
		cout << "MyException的析构调用" << endl;
	}

	void printError()
	{
		this->m_A = 100;
		cout << "error" << m_A << endl;
	}

	int m_A;

};

void doWork()
{
	throw  &MyException();
}

void test01()
{
	try
	{
		doWork();
	}
	catch (MyException *e) //MyException e,会多开销一份数据
	{

		//e->printError();
		//e->printError();
		//e->printError(); //指向非法内存空间,不应该这么做

		cout << "捕获异常" << endl;

		//delete e; //靠自觉 释放对象
	}

}


int main(){


	test01();

	system("pause");
	return EXIT_SUCCESS;
}

输出

MyException的默认构造
MyException的析构调用
捕获异常

main.cpp

// 44.异常.cpp : 定义控制台应用程序的入口点。
//

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

class MyException
{
public:
	MyException()
	{
		cout << "MyException的默认构造" << endl;
	}
	MyException(const MyException & e)
	{
		cout << "MyException的拷贝构造" << endl;
	}

	~MyException()
	{
		cout << "MyException的析构调用" << endl;
	}

	void printError()
	{
		this->m_A = 100;
		cout << "error" << m_A << endl;
	}

	int m_A;

};

void doWork()
{
	throw  MyException();
}

void test01()
{
	try
	{
		doWork();
	}
	catch (MyException e) //MyException e,会多开销一份数据
	{

		//e->printError();
		//e->printError();
		//e->printError(); //指向非法内存空间,不应该这么做

		cout << "捕获异常" << endl;

		//delete e; //靠自觉 释放对象
	}

}


int main(){


	test01();

	system("pause");
	return EXIT_SUCCESS;
}

输出

MyException的默认构造
MyException的拷贝构造
捕获异常
MyException的析构调用
MyException的析构调用

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值