异常处理
异常处理就是处理程序中的错误。所谓错误是指在程序运行的过程中发生一些异常事件(如:除0溢出,数组下标越界,所要读取的文件不存在,空指针,内存不足等等)
try 试图执行{}中的内容,在可能出现异常的地方,抛出异常throw,try下面catch捕获异常。如果不想处理异常,继续向上抛出 throw,如果没有任何处理异常的地方,那么成员调用terminate函数,程序中断
int myDevice(int a, int b)
{
if (b == 0)
{
//如果b异常 抛出异常
//return -1;
//throw 3.14; //抛出double类型的异常,异常必须处理catch(double)
throw -1;
}
return a / b;
}
void test01()
{
int a = 10;
int b = -10;
int ret = myDevice(a, b); //早期如果返回-1,无法区分到底是结果还是异常
//C++中异常处理
try
{
myDevice(a, b);
}
catch (int) //捕获异常
{
cout << "int类型异常捕获" << endl;
}
catch(...)
{
cout << "其他类型异常捕获" << endl;
}
}
自定义异常进行捕获
//自定义异常类
class myException
{
public:
void printError()
{
cout << "自定义的异常" << endl;
}
};
int myDevice(int a, int b)
{
if (b == 0)
{
throw myException(); //匿名对象
}
return a / b;
}
void test01()
{
int a = 10;
int b = 0;
try
{
myDevice(a, b);
}
catch (myException e)
{
e.printError();
}
}
栈解旋
从try开始 到throw 抛出异常之前 所有栈上的对象 都会释放 这个过程称为栈解旋
构造和析构顺序是相反的
//自定义异常类
class myException
{
public:
void printError()
{
cout << "自定义的异常" << endl;
}
};
class Person
{
public:
Person()
{
cout << "默认构造" << endl;
}
~Person()
{
cout << "析构" << endl;
}
};
int myDevide(int a, int b)
{
if (b == 0)
{
//栈解旋
//从try开始 到throw 抛出异常之前 所有栈上的对象 都会释放 这个过程称为栈解旋
//构造和析构顺序是相反的
Person p1;
Person p2;
throw myException(); //抛出异常
}
return a / b;
}
void test01()
{
int a = 10;
int b = 0;
try
{
myDevide(a, b);
}
catch (myException e)
{
e.printError();
}
}
异常接口声明
只想抛出一个特定类型的异常,其他的都不抛出
只能在Qt或Linux下应用
void func() throw(int) //throw(int)只能抛出int类型异常,throw()不抛出任何类型异常
{
throw 1;
}
void test01()
{
try
{
func();
}
catch(int)
{
qDebug << "int类型异常捕获" << endl;
}
}
异常变量的生命周期
myException e因为调用拷贝构造,会多开销一份数据
myException *e,不new的话会提前释放对象 new自己管理delete
myException &e,容易些,而且 就一份数据
class myException
{
public:
myException()
{
cout << "myException的默认构造" << endl;
}
~myException()
{
cout << "myException的析构构造" << endl;
}
myException(const myException &e)
{
cout << "myException的拷贝构造" << endl;
}
};
void doWork()
{
throw myException();
}
void test01()
{
try
{
doWork();
}
catch (myException &e) //myException e因为调用拷贝构造,会多开销一份数据
{
cout << "捕获异常" << endl;
}
}
异常的多态使用
利用多态来实现 printError同一个接口调用,抛出不同的错误对象,提示不同的错误
class BaseException
{
public:
virtual void printError()
{
}
};
class NullPointerException :public BaseException
{
public:
virtual void printError()
{
cout << "空指针异常" << endl;
}
};
class OutofRangeException :public BaseException
{
public:
virtual void printError()
{
cout << "越界异常" << endl;
}
};
void doWork()
{
throw NullPointerException(); //调用空指针异常
//throw OutofRangeException(); //调用越界异常
}
void test01()
{
try
{
doWork();
}
catch (BaseException &e)
{
e.printError();
}
}
使用系统标准异常
//系统提供标准异常,要包含头文件
#include <stdexcept>
class Person
{
public:
Person(string name, int age)
{
this->m_Name = name;
if (age < 0 || age>0)
{
//抛出越界异常
//throw out_of_range("年龄越界了");
throw length_error("长度越界");
}
}
string m_Name;
int m_Age;
};
void test02()
{
try
{
Person p("Tom", 300);
}
catch (out_of_range &e)
{
cout << e.what() << endl;
}
catch (length_error &e)
{
cout << e.what() << endl;
}
}
编写自己的异常类
//编写自己的异常类, 继承系统标准异常类
class MyOutofRangeException :public exception
{
public:
MyOutofRangeException(string errorInfo)
{
this->m_ErrorInfo = errorInfo;
}
virtual ~MyOutofRangeException()
{
}
virtual char const* what() const
{
//string 转char*:.c_str()
return this->m_ErrorInfo.c_str();
}
string m_ErrorInfo;
};