Symbian os 异常处理之TRAP ,TRAPD

    大家开始接触symbian的异常处理的时候可能都会有一个问题,标准c++不是有了try{}catch{}了么 ,symbian 开发者干吗还高个trap,和trapd出来呢?其实在symbian设计的时候,标准c++并不包含异常处理。后来标准c++有异常处理的时候,发现c++的异常处理根本不适合处理能力受限的移动设备 ,因为标准c++的异常处理会隐式的让编译后的代码变得多。因为标准c++不管程序是否发生异常,它都会将异常代码编译加入到RAM中。因此标准c++效率不如trap和trapd高。下面仔细介绍这个symbian的基础机制。

 

      symbian为了防止构造对象的时候产生异常,就引入了 enum Tleave{ELeave};并且重载了new操作符,定义如下:

inline TAny* operator new (TUnit ,TLeave);

inline TAny* operator new (TUnit asize, TLeave)

{return User::AllocL(aSize);}

这些都是定义在CBase 类里面的。在symbian里所有C类都继承于CBase,所以只要是C类(只能放在堆上)都可以像这样分配空间是要接收一个TLeave作为参数:

CClass *objiect = new(ELeave)CClass(); 当内存不足是就会跳出构造函数,将用如下方式进一步检测ELeave的值:

TInt result;
TRAP(result, MayLeaveL());
if (KErrNone!=result)
{
// Handle error
}

...
User::LeaveIfError(result);

或者

TRAPD(result, MayLeaveL())
if (KErrNone==result)
{
TRAPD(result, MayAlsoLeaveL())
}
...
User::LeaveIfError(result);result小于0时就调用User::LeaveIfError(result);

如果分配成功,就不用再进一步检测了。

 

    调用TRAP和TRAPD之后,只安全释放函数中T类数据类型的数据:

     void FunctionMayLeaveL()
{
// Allocates ironChicken on the heap
CTestClass* ironChicken = CTestClass::NewL();
// If NewL() didn’t leave, ironChicken was allocated successfully
ironChicken->FunctionDoesNotLeave();

}

TRAPD(erro,FunctionMayLeaveL());

当leave时函数自动清除指针型变量TAny*(*ironChicken 和TAny*是同一种类型,指针无类型),所以ironChicken 被清除了,而由于CTestClass属于C类没有被清除,这块内存这时没有任何指针来认领它,这块内存就成了孤儿内存,产生了内存泄露。这是TRAP,TRAPD不足之处,不过可以用CleanupStack(清洁栈)来处理。在下一篇文章中将进行详细介绍。

      所以一般在函数里面有C类并且有有可能产生异常的操作时要配合清洁栈来使用TRAP,TRAPD,这是一个相当完美的组合。不过也不要用的太放肆。symbian是一个以服务器/客户端为模式转换(内核权限与用户权限之间的转换)的系统,而每次进出

TRAP(int error, functionl())时;都会引发内核执行TTrap::Trap()和TTrap::UnTrap().所以太豪放的用的话会使代码的效率降低。那怎么办呢?简单了去了:

MyNonLeavingFunction()
{
TRAPD(result, MyLeavingFunctionL());
// Handle any error if necessary
return (result);
}
void MyLeavingFunctionL()
{
FunctionMayLeaveL();
AnotherFunctionWhichMayLeaveL();
PotentialLeaverL();
}

这就相当于把所有可能产生异常的代码用一个TRAP来处理就OK了。其实我们的framework.h里就有这样的函数TRAPD(error,callExampleL()); 所以呢。只要用framework.h 的大可不必自己去写TRAP,但是要注意把可能产生异常的函数末尾要加个‘L’,什么函数会产生异常呢?满足如下三个条件之一者就有可能产生异常:

1.调用了可能产生异常的语句而没有捕获的。

2.用了指明Leave的系统函数如User::Leave,User::LeaveIfError().

3.使用了TLeave参数的重载操作符new。

以上是本人一些浅薄的见解 ,如有误欢迎指正。

   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值