|
C++异常处理(try cat ch 及hrow)机制为这些问题提供了一些解决方案,但并没有在Symbian OS 中使用,这是因为其代码开销比较大。相反,Symbian OS 提供其本身的异常处理系统。
Symbian OS 中的解决方案
各种 Symbian OS 应用能使用下列规则获得有效的异常处理:
规则 1:所有可以异常退出的函数其名字都以字母‘L’结尾。各种异常都顺着调用栈通过一些“异常函数”向后传递,直到被一个 “trap harness(捕获模块)” 捕获为止。通常在针对各种控制台应用的 E32Main( ) 主函数中实现这一功能,或作为图形用户界面程序的应用框架的一部分提供。
规则 2:当在堆中分配内存时,如果指向该内存的指针是一个自动变量(即,不是成员变量),必须将其推入清除堆栈中,以便当发生异常退出时能被释放掉。所有被推入该清除堆栈的对象都必须在销毁前弹出。
规则 3:C++构造函数或解构函数是不允许异常退出或失败的。因而,如果某个对象的构造函数出现资源不足错误而失败,所有可能导致失败的指令都必须移出该 C++构造函数,并将它们放入到 Construc tL()函数中,在 C++构造函数完成之后才调用该函数。这一过程被称为两阶段构造。
规则1:异常退出函数和捕获模块
异常退出函数
Symbian OS 中的函数并不返回出错代码,而是一出现资源不足错误时就异常退出。一个异常退出就是对 User::Leave()的调用,它导致程序的执行被立即返回到捕获模块中,该函数就在其中执行。所有可以异常退出的函数都以字母‘L’结尾。这使得程序员们明了:该函数是可以异常退出的。例如:void MyFunctionL()
{ iMember = new (ELeave) CMember;
iValue = AnotherFunctionL();
User::LeaveIfError(iSession.Connect()); }
MyFunctionL
中的每一行都可能导致异常退出。其中的任何一行都使MyFuncti onL成为一个异常退出函数。然而需要注意的是:应用程序代码中很少有必要使用 TRAP ,因为应用框架已经在适当的地方提供了这些捕捉错误的代码(TRAP) ,也提供了相应的处理代码。在正常编码过程中并不需要使用错误捕捉代码。一般说来,处理各种异常退出的方法很简单,就是在函数名字后面加上一个字母‘L’,从而让其能顺着函数传递。
new (ELeave)运算符
在Symbian OS 中,New运算符失败的可能性很高,以至该运算符已经被重置而带上了一个参数,即Eleave。当用这个参数调用 New时,如果没能分配到所需的内存空间,被重置的 new运算符就会异常退出。这一功能已经得到了全局性实现,所以,任何类都可以使用该运算符的 new(ELeave) 版本,如:CSomeObject* myObject = new CSomeObject;
if (!myObject) User::Leave(KErrNoMemory);
Can be replaced in by:
CSomeObject* myObject = new (ELeave) CSomeObject;
NewL()和 N ewLC()惯例习惯上,Symbian OS 的一些类经常实现 NewL()和 NewLC()方法。这两个方法在类定义中被声明为static方法,这就使得它们可以在该类的一个实例存在之前就被调用。可以使用类范围来调用它们。如:CSomeObject* myObject = CSomeObject::NewL();NewL()在堆上创建了该类的一个新实例,当出现内存不足错误时,它就会异常退出。对简单对象来说,这仅仅涉及到对 new (ELeave) 的调用。然而,对复合对象来说,它要用到两阶段构造(请见下面对“规则 3 ”的讲述)。
NewLC()在 [1] [2] 下一页
|