symbian C++编程注意规则

### Symbian C++编程注意规则####一、引言与目标读者本文档旨在为使用C++语言为Symbian OS 6.x/7.0s开发应用程序的开发者提供一套详细的编码准则和建议。根据80/20法则,开发者往往需要花费大量时间来修复开发过程中出现的一小部分问题。因此,本文档的目标是帮助开发者解决这些常见的20%的问题,从而提高开发效率。 ####二、内存管理**2.1关于清理堆栈(CleanupStack)** ##### 2.1.1所有程序都应检查“资源耗尽”错误在Symbian OS中,由于内存资源有限,开发者需要特别关注内存的使用情况。所有程序都应该具备检测资源是否耗尽的能力,并且在资源耗尽时能够妥善处理。例如,当内存分配失败时,应该通过检查返回值或者使用异常处理机制来确保程序的健壮性。 ##### 2.1.2传统的调试方法在Symbian OS之前,许多开发者使用传统的调试方法来处理内存管理问题,比如使用`malloc()`和`free()`来手动管理内存。这种方法容易导致内存泄漏和资源耗尽等问题。 ##### 2.1.3使用传统方法的问题传统的内存管理方法在Symbian OS中存在一些固有的缺陷: - **难以追踪**:手动管理内存使得内存泄漏等问题难以追踪。 - **效率低下**:频繁地调用`malloc()`和`free()`会导致效率低下。 - **安全性问题**:不当的内存管理可能导致程序崩溃。 ##### 2.1.4 Symbian OS中的解决方案为了克服这些问题,Symbian OS引入了一系列新的内存管理机制,如`CleanupStack`,以帮助开发者更有效地管理内存资源。 **2.2规则1:异常退出函数和捕获模块** ##### 2.2.1异常退出函数Symbian OS提供了异常退出函数`User::Leave`,用于处理资源耗尽等错误情况。当资源耗尽时,该函数将抛出异常,从而允许程序进行适当的清理工作。 ##### 2.2.2 `new(ELeave)`运算符是一种特殊的内存分配操作,当内存分配失败时,会自动抛出一个`ELeave`异常。这种机制可以确保程序能够在资源耗尽的情况下优雅地退出。 ##### 2.2.3 `NewL()`和`NewLC()`惯例Symbian OS推荐使用`NewL()`和`NewLC()`函数来分配内存。`NewL()`用于永久分配,而`NewLC()`则用于临时分配。这些函数内部使用`new(ELeave)`运算符,能够自动处理资源耗尽的情况。 ##### 2.2.4使用捕获模块:`TRAP`和`TRAPD` `TRAP`和`TRAPD`是两种用于捕获异常的机制。`TRAP`用于捕获并忽略异常,`TRAPD`则捕获并处理异常。这两种机制可以帮助开发者更好地控制程序的行为,特别是在资源耗尽的情况下。 **2.3规则2:使用清理堆栈** ##### 2.3.1为何需要清理堆栈(`CleanupStack`)是Symbian OS中一种重要的内存管理机制,它允许开发者自动清理分配的资源。清理堆栈可以确保即使在异常情况下,也能释放已分配的资源。 ##### 2.3.2使用清理堆栈开发者可以通过在函数入口处调用`CleanupStack::PushL()`,并在函数退出时调用`CleanupStack::Pop()`来使用清理堆栈。这种方式可以确保无论程序如何退出,清理堆栈都会释放所有被管理的资源。 **2.4规则3:两阶段构造** ##### 2.4.1用`NewL()`和`NewLC()`实现两阶段构建在Symbian OS中,推荐使用两阶段构造来创建对象。第一阶段通过`NewL()`或`NewLC()`分配内存;第二阶段通过调用对象的构造函数完成初始化。这种方式可以确保即使在构造过程中出现问题,也可以安全地清理资源。 **2.5公共错误** ##### 2.5.1误用`TRAP`和`TRAPD`错误地使用`TRAP`和`TRAPD`可能导致程序行为异常。例如,如果在不适当的情况下使用`TRAP`忽略异常,可能会导致未处理的错误累积,最终导致程序崩溃。 ##### 2.5.2错误使用`new`运算符直接使用标准的`new`运算符而不是`new(ELeave)`可能导致程序无法正确处理资源耗尽的情况。 ##### 2.5.3错误使用后缀`'L'`在Symbian OS中,后缀`'L'`表示一个持久对象,而`'LC'`表示一个临时对象。错误地使用这些后缀可能会导致内存泄漏或资源管理问题。 **2.6内存泄漏**内存泄漏是指程序在运行过程中没有释放不再使用的内存。为了避免内存泄漏,开发者需要确保所有的资源都能被适当地释放。 ##### 2.6.1使用WINS模拟器中的工具WINS模拟器提供了一些工具,可以帮助开发者检测和定位内存泄漏问题。利用这些工具,开发者可以更容易地识别哪些地方发生了内存泄漏,并采取相应的措施。 **2.7检查和严重提示(Asserts and Panics)**在Symbian OS中,开发者可以使用断言(asserts)来验证程序的状态,并使用严重提示(panics)来报告不可恢复的错误情况。这些机制有助于确保程序的稳定性和可靠性。 ####三、系统资源的使用本节将讨论如何减少ROM和RAM的使用,以及如何有效地管理这些资源。 **3.1重要性**在移动设备上,ROM和RAM资源通常比桌面环境更为有限。因此,开发者需要特别注意优化代码,以减少对这些资源的占用。 **3.2减少代码量** ##### 3.2.1不必要的导出函数导出不必要的函数会增加代码大小。开发者应当只导出真正需要在其他模块中访问的函数。 ##### 3.2.2复制和粘贴避免重复代码。使用复制和粘贴的方法虽然简单,但会导致代码膨胀,并增加维护难度。 ##### 3.2.3明显不可分解的函数大型不可分解的函数不仅难以阅读和维护,而且可能会增加代码大小。开发者应该尽可能地将大型函数分解为多个较小的函数。 ##### 3.2.4过分的`TRAP`模块过多使用`TRAP`模块会增加代码复杂度和大小。开发者应当谨慎使用,并确保每个`TRAP`模块都是必要的。 ##### 3.2.5调试发行代码在发行版中包含调试信息会显著增加代码大小。开发者应当确保在发布之前移除所有调试代码。 ##### 3.2.6不必要的虚函数会增加类的大小。只有在确实需要的时候才使用虚函数。 ##### 3.2.7使用公共控件尽可能使用已经经过优化的公共控件,而不是自己重新实现相似的功能。 **3.3减少使用RAM** ##### 3.3.1使用位字段(bitfields),而不是太多的`TBool`类型在某些情况下,使用位字段而不是`TBool`类型可以节省内存空间。但是,开发者需要注意位字段的使用可能会降低代码的可读性和维护性。 ##### 3.3.2阵列粒度的使用警示对于较大的数组,考虑使用更细粒度的数据结构来减少内存占用。例如,使用指针数组代替单一的大数组。 ##### 3.3.3避免全局数据全局变量会占用更多的RAM空间。尽可能地减少全局变量的使用,尤其是在动态分配的全局变量上。 ##### 3.3.4小心基类的成员数据基类中的成员数据也会占用RAM空间。确保基类的设计尽可能地精简。 ##### 3.3.5正确使用清理堆栈合理使用清理堆栈可以减少RAM的使用量。确保所有的资源都被正确地清理和释放。 ##### 3.3.6尽早删除在不再需要资源时尽早释放它们。这有助于减少RAM的占用。 ##### 3.3.7用最大数据集进行硬件测试在开发过程中使用最大的数据集进行测试,可以帮助发现潜在的内存使用问题。 ##### 3.3.8分解复杂的长运算将复杂的计算过程分解为多个步骤,可以在一定程度上减少RAM的使用。 **3.4减少堆栈的使用** ##### 3.4.1正确使用描述符在Symbian OS中,描述符用于存储字符串和其他数据。开发者应当正确使用描述符,以减少堆栈的使用。 ##### 3.4.2小心使用递归,在限度内生成递归算法可能会消耗大量的堆栈空间。开发者应当小心使用递归,并考虑使用迭代方法作为替代方案。 ##### 3.4.3注意日志代码过度的日志记录会消耗大量的堆栈空间。开发者应当合理地使用日志功能,只记录必要的信息。 **3.5盘容量降低的处理**当存储空间不足时,开发者需要采取一些措施来处理这种情况。例如,可以考虑将非关键数据移动到外部存储设备上,或者提示用户释放一些空间。 ####四、生成(Build)ARM目标文件**4.1概述**生成ARM目标文件涉及到编译、链接等多个步骤。开发者需要确保生成的目标文件符合Symbian OS的要求。 **4.2函数导出**正确的函数导出对于确保模块之间的正确交互至关重要。开发者应当遵循Symbian OS的导出函数指南。 **4.3来自PETRAN的“MyDll.DLL has (un)initialized data”错误** PETRAN是Symbian OS中的一个工具,用于检测模块中是否存在未初始化的数据。这个错误通常意味着模块中有未正确初始化的数据。开发者需要检查他们的代码,确保所有数据都在使用前得到正确的初始化。 ###总结本文档详细介绍了Symbian OS C++编程中的一些重要规则和最佳实践,包括内存管理、系统资源的使用以及生成ARM目标文件等方面。遵循这些规则和建议可以帮助开发者编写更加高效、稳定的Symbian OS应用程序。
pdf 文件大小:379.76KB