异常基本语法:
第一种情况:
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();
}
建议写自己的异常类的时候都要重载一个等号和重写拷贝构造