C++:异常

一.异常的基本概念

1.异常: 出错后,将出错问题返回给调用处
2.c语言的异常处理比较简单,容易出错(如下),c++处理异常不容易出错

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string.h>
#include <string>
using namespace std;
int  mydive(int a, int  b)
{
	if (b == 0)
		return -1; //errno  = 2

	return  a / b;
}

void  test01()
{
	int ret = mydive(1, -1);
	if (ret == -1)
	{
		cout << "除数为0" << endl;//perror("");
	
	}
}

int  main() {

	test01();

}

二.C++处理异常

异常的基本语法:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string.h>
#include <string>
using namespace std;
int  mydive(int a, int  b)
{
	string str = "hello";
	if (b == 0)
		throw  str;//处理异常 抛出异常 抛出一个类型

	return  a / b;
}
void   test01()
{
	//尝试捕获异常
	try
	{
		mydive(2,0);
	}
	catch (char)//如果没有捕获的抛出的异常 程序会被终止
	{
		//cout << "捕获了一个char类型的异常" << endl;
		throw 'a';
	}
	catch (int)
	{
		cout << "捕获了一个int类型的异常" << endl;
	}
	catch (double)
	{
		cout << "捕获了一个double类型的异常" << endl;
	}
	catch (...)
	{
		cout << "捕获了一个其他类型的异常" << endl;
	}
}
int main()
{
	try {
		test01();
	}
	catch (char)
	{
		cout << "捕获了一个char类型的异常" << endl;
	}
}

三.栈解旋

在try到throw之间定义的对象,在throw之后会被释放

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string.h>
#include <string>
using namespace std;
class Person
{
public:
	Person(string name)
	{
		cout << "构造" << endl;
		this->name = name;
	}
	~Person()
	{
		cout << "析构" << endl;
	}
	string name;
};
void  fun()
{
	Person p2("bob");
	Person p3("peter");
	cout << "001" << endl;
	throw 1;
}

void test01()
{
	try
	{
		Person p1("lucy");
		fun();
	}
	catch (int)
	{
		cout << "002" << endl;
		cout << "捕获到异常" << endl;
	}

}

int  main()
{
	test01();
	return 0;
}

结果如下:
在这里插入图片描述

四.异常接口声明

一:可以抛掷A,B,C,D和子类型的异常

void fun() throw(A,B,C,D);

二:可以抛掷任意类型的异常

void fun();

三:不可以抛掷任意类型的异常

void fun) throw();

注意:如果抛掷的异常类型和声明的类型不一致,那么会调用unexpected函数,它的默认行为是调用terminate函数终止程序。

五.异常变量生命周期

抛出的匿名对象的生命周期在catch里面

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string.h>
#include <string>
using namespace std;
class Myexception
{
public:
	Myexception()
	{
		cout << "构造函数" << endl;
	}
	~Myexception()
	{
		cout << "析构函数" << endl;
	}
	void  error()
	{
		cout << "my  error" << endl;
	}

};
class Myexception1
{
public:
	Myexception1()
	{
		cout << "构造函数" << endl;
	}
	~Myexception1()
	{
		cout << "析构函数" << endl;
	}
	void  error()
	{
		cout << "my  error" << endl;
	}

};
void  fun()
{
	Myexception p1;
	//throw Myexception();//如果抛出匿名对象 他的声明周期在catch里面
	throw p1;/*p1生命周期在throw之前,实际抛出的是一个匿名对象,也就是说,在抛出的时候会创建一个匿名对象*/

}
void  test01()
{
	try {
		fun();

	}
	catch (Myexception &p)
	{
		p.error();
	}
	catch (Myexception1 &p)
	{
		p.error();
	}
}
int main()
{
	test01();
	return 0;
}

结果如下:
在这里插入图片描述

六.异常的多态使用

1.做法就是抛出任意一个子类,用父类引用或指针去接引
2.这样做的好处在于,当我们一个程序可能有多个类会抛出,这时可能要对各个类进行识别处理,会多次用到catch,这样的代码显得多且杂乱。这时我们只需要给各个类设定一个共同的基类,用虚函数实现异常的多态使用

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string.h>
#include <string>
using namespace std;
//基类
class Myexception
{
public:
	virtual void  error() = 0;
};

class Out_of_range:public Myexception
{
public:
	void  error()
	{
		cout << "Out_of_range" << endl;
	}
};

class Bad_cast :public Myexception
{
public:
	void  error()
	{
		cout << "Bad_cast" << endl;
	}
};
void fun()
{
	//throw Out_of_range();
	throw Bad_cast();
}
void  test01()
{
	try
	{
		fun();
	}
	catch (Myexception &p)
	{
		p.error();
	}
}
int  main()
{
	test01();
	return 0;
}

七.基于C++异常库编写自己的异常类

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string.h>
#include <string>
//exception
#include <stdexcept>
using namespace std;
class Longlongerror :public exception
{
public:
	Longlongerror(string  data)
	{
		this->data = data;
	}
	Longlongerror(char *  data)
	{
		this->data = data;
	}
	const char * what() const
	{
		 return data.c_str(); //将string类强制转换成从const char*
	}
	string  data;

};

void fun()
{
	throw Longlongerror("长长的错误");
}
void  test01()
{
	try
	{
		fun();
	}
	catch (exception &p)
	{
		cout << p.what() << endl;
	}
}
int  main()
{
	test01();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值