关于C++异常方面的问题
异常:当一个函数发现自己无法处理的错误时抛出异常,让函数的调用者直接或间接的处理问题
1、传统处理错误的方法:
(1)终止程序
(2)返回错误码
(3)返回合法值,让程序处于某种非法的状态
(4)调用一个预先设置的出现错误时调用的函数 ---回调函数
2、异常的抛出和捕获
(1)异常是通过抛出对象而引发的,该对象的类型决定了应该激活哪个处理代码
(2)被选中的处理代码是调用链中与该对象类型匹配且离抛出异常位置最近的那一个
(3)抛出异常后会释放局部存储对象,所以被抛出的对象也就还给了系统,throw表达式会初始化一个抛出特殊的异常对象副本(匿名对象),异常对象由编译管理,异常对象在传给对应的catch处理之后撤销
抛出异常的时候,会暂停当前函数的执行
3、异常捕获的规则
异常对象的类型与catch说明符的类型完全匹配
只有以下几种情况例外
(1)允许从非const对象到const的转换
(2)允许从派生类型到基类类型的转换
(3)将数组转换为指向数组类型的指针,将函数转换为指向函数类型的指针
保证不能在构造函数和析构函数中抛出异常,否则会导致对象不完整或没有完全初始化或者内存泄漏
4.模拟实现Exception类
#include
#include
using namespace std;
class Exception
{
public:
virtual const char* what()const = 0; //声明为纯虚函数
Exception(int errId, string errMsg)
:_errID(errId)
, _errMsg(errMsg)
{}
protected:
int _errID;
string _errMsg;
};
class BadAlloc :public Exception
{
public:
BadAlloc(const char* msg = "")
:Exception(1, msg)
{
_errMsg = _errMsg + ":alloc memory failed";
}
virtual const char* what()const
{
return _errMsg.c_str();
}
};
template
//模板函数,模拟new
T* New()
{
T* p= (T*)malloc(sizeof(T));
if (p == 0)
{
throw BadAlloc("New failed:");
}
return new(p) T; //new定位表达式
}
struct AA
{
AA()
{
cout << "AA()" << endl;
}
};
int main()
{
try
{
AA* p1 = New
();
int* p2 = New
(); } catch (BadAlloc e) { cout << e.what() << endl; } catch (const Exception& e) { cout << __LINE__ << e.what() << endl; } }