C++高级机制-异常

C++异常机制的实现方式和开销分析:

http://baiy.cn/doc/cpp/inside_exception.htm

C++ 异常 与 ”为什么析构函数不能抛出异常“ 问题:

http://www.cnblogs.com/zhyg6516/archive/2011/03/08/1977007.html


1.当无异常抛出时,其开销就是在函数调用的时候将函数注册到异常处理链中,这些开销很小。

2.但是当异常抛出时,其开销就大了,回溯异常链,用RTTI比配类型,调用析构;但是比传统的那种返回值,层层返回,效率也不会太差。


带来好的好处是代码好维护,减少重复的出错处理代码,并且与逻辑代码分开。



C++标准异常实现的一些主要结构:

编译时确定的:

一. 每个函数一个的EHDL结构,它包括:

1.“try”块表:tblTryBlocks :记录函数中每个try包含的catch入口,参数类型等。

2.“栈回退表”:tblUnwind:存放栈回退所需的析构函数地址与对象在栈中的偏移(偏移是编译可确定的,而对象的实际地址则随函数调用情况的不同而有变化)。


二.每个函数中附加的多个nStep值,标记到目前代码为止需要撤销析构的对象。



运行时确定的:

一.每个函数调用其他函数时将当前的nStep值放入栈中的nStep。此外throw时也会作此操作。以索引“栈回退表”来撤销对象。

二.将当前函数的EHDL地址压入栈中(地址编译时确定,只是运行时压入栈中)

三.将当前的piPrev指向调用链中前一函数的EXP结构。并将当前的EXP结构地址注册到TLS(thread local storage)或同样功能的实现。 


上面三个部分组成的EXP结构如下:

struct EXP

{

    EXP *ipPrev; 

    EHDL *piHandle;

    int nStep;

}     


struct EHDL

{

    UNWINDTBL tblUnwind[];

    TRYBLOCK tblTryBlocks[];

}


struct UNWINDTBL

{

    int nNextldx;

    void (*pfnDestroyer)(void* this);

    void* pObj;

}


struct TRYBLOCK

{

    int nBeginStep; //同过当前nStep来定位属于哪个try

    int nEndStep;

    CATCHBLOCK tblCatchBlocks[];

}



struct CATCHBLOCK

{

    type_info *piType;//RTTI,typeid确定类型是否相同

    void *pCatchBlockEntry;

}




1.析构函数中不能抛出异常,会出现内存泄露等情况的资源泄露,但析构函数自己把异常处理了的话,程序是可运行的。否则程序将异常退出。因为此时失去了异常回溯的节点,前面的异常还待处理又如何来处理新的异常。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值