异常可以跨函数
异常必须处理
1、
#include<iostream>
using namespace std;
//c++异常机制 跨函数
//c++异常必须处理 不能留,否则报错
int divided(int x, int y)
{
if (y == 0)
throw y; //抛异常
return (x / y);
}
void test01()
{
int x = 10, y = 0;
//试着去捕获异常
try
{
divided(x, y);
}
catch (int y) //异常是根据类型进行匹配
{
cout << "除数为" << y <<"!"<< endl;
}
}
void CallDivide(int x, int y)
{
divided(x, y);
}
//如果异常抛到顶层,还没有处理这个时候程序后挂掉terminal()
//a调用b,b调用c,c调用d函数 a-->b-->c-->d
//d抛出异常,c没有处理,则继续给b,b还没有处理给a,则异常给a,a处理(catch)即可。若a还不处理,则报错,程序挂掉
void test02() {
try
{
CallDivide(1, 0);
}
catch (int e)
{
cout << "除数为" << e << endl;
}
}
int main()
{
test01();
cout << "------------------" << endl;
test02();
}
2、栈解旋
#include<iostream>
using namespace std;
class person {
public:
person()
{
cout << "对象构建" << endl;
}
~person()
{
cout << "对象析构" << endl;
}
};
int divide(int x, int y)
{
person p1, p2;
if (y == 0)
throw y;
return x / y;
}
//栈解旋:try catch中调用函数发生异常时,函数内的局部变量会被析构掉
void test01()
{
try {
divide(10, 0);
}
catch (int e)
{
cout << "异常捕获!" << endl;
}
}
int main()
{
test01();
return 0;
}
3、异常接口的声明
#include<iostream>
using namespace std;
//这个函数只能抛出int,float,char三种类型异常,抛出其他报错
void func() throw(int, float, char)
{
throw "abc";
}
//不能抛出任何类型异常
void func02() throw()
{
throw - 1;
}
//抛出任何类型异常
void func03()
{
throw - 2;
}
int main()
{
try {
func();
}
catch (char* str)
{
cout << str << endl;
}
catch (int e)
{
cout << "异常!" << endl;
}
catch (...) //...代表所有异常类型
{
cout << "捕获所有未知类型异常" << endl;
}
}
4、异常类型
#include<iostream>
using namespace std;
void func01(){
throw 1; //抛出int类型异常
}
void func02() {
throw "exception"; //抛出char*类型异常
}
class MyException {
public:
MyException(char* str) {
error = new char[strlen(str) + 1];
strcpy(error, str);
}
void what() {
cout << error << endl;
}
MyException(const MyException& ex){ //拷贝构造
this->error = new char[strlen(ex.error) + 1];
strcpy(this->error, ex.error);
}
MyException& operator=(const MyException& ex) { //等于构造
if (this->error != NULL)
{
delete[] this->error;
this->error = NULL;
}
this->error = new char[strlen(ex.error) + 1];
strcpy(this->error, ex.error);
}
MyException()
{
if (error != NULL)
{
delete[] error;
}
}
public:
char* error;
};
void func03() {
throw MyException("我刚写的异常!");
}
void test01(){
try {
func01();
}
catch (int e) {
cout << "异常捕获!" << endl;
}
//----------------------------------------
try {
func02();
}
catch (char* e) {
cout << "异常捕获!" << endl;
}
//-----------------------------------------
try {
func03();
}
catch (MyException e) {
e.what();
}
}
int main()
{
MyException e1=MyException("dd"); //拷贝构造
MyException e2 = e1; //等于构造
test01();
return 0;
}
运行结果:
5、异常生命周期
#include<iostream>
using namespace std;
class MyException {
public:
MyException() {
cout << "构造函数" << endl;
}
MyException(const MyException& ex) { //拷贝构造
cout << "拷贝构造函数" << endl;
}
~MyException() {
cout << "析构函数" << endl;
}
};
void func() {
//throw MyException(); //创建匿名对象,调用构造函数
//throw &(MyException()); //创建匿名对象,调用构造函数
throw new MyException();
}
void test01() {
//普通类型元素 引用 指针
//普通类型元素 catch处理完后就析构
//引用的话 不用调用拷贝构造 catch处理完后就析构
//指针的话,需要new一个异常,否则在捕捉异常前就已经析构
try {
func();
}
//catch (MyException e) { //用MyException元素接,相当于将上面的MyException()拷贝一份传给e,调用拷贝构造
// cout << "异常捕获" << endl;
//}
//catch (MyException& e) { //用MyException元素接,相当于将上面的MyException()拷贝一份传给e,调用拷贝构造
// cout << "异常捕获" << endl;
//}
catch (MyException* e) { //用MyException元素接,相当于将上面的MyException()拷贝一份传给e,调用拷贝构造
cout << "异常捕获" << endl;
delete e;
}
}
int main()
{
test01();
return 0;
}
运行结果:
6、c++异常库举例
#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;
};
void test01(){
Person p;
try {
p.setAge(1000);
}
catch (out_of_range e) {
cout << e.what() << endl;
}
catch (exception e) {
cout << e.what() << endl;
}
}
class MyOutOfRange : public exception {
public:
MyOutOfRange(char* error) {
pError = new char[strlen(error) + 1];
strcpy(pError, error);
}
virtual char const* what() const {
return pError;
}
MyOutOfRange() {
if (pError != NULL) {
delete[] pError;
}
}
public:
char* pError;
};
void func02() {
throw MyOutOfRange("我自己抛出的异常");
}
void test02() {
try {
func02();
}
catch (exception& e) {
cout << e.what() << endl;
}
}
int main() {
test01();
test02();
return 0;
}
运行结果:
7、继承在异常中的应用
#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* target, char* source){
if (target == NULL){
//cout << "目标空间为空" << endl;
throw TargetSpaceNullException();
return;
}
if (source == NULL) {
throw SourceSpaceNullException();
//cout << "源空间为空" << endl;
return;
}
int len = strlen(source)+1;
while (*source != '\0') {
*target = *source;
source++;
target++;
}
}
int main()
{
char* source = "abcdefg";
char buf[1024] = { 0 };
cout << "copy" << endl;
try {
copy_str(NULL, source);
}
catch (BaseMyException& e) {
e.what();
}
cout << buf << endl;
return 0;
}