在Symbian C++编程程中遇到的一个最棘手问题就是内存泄露,如果内存泄露没有用正确方法去解决,则很容易衍生出一些难以解释的错误。 为此我专门总结出几条防止内存泄露的原则。
四种基本的类
T类一般都是在栈上分配的,不需要明确的分配操作,也不需要实现复制构造函数。T类的析构函数不会被执行,所以T类的成员数据不可以使用指针,引用,句柄或含有析构函数的类的类型,所以T类的成员数据只能是固有类型和其他T类类型。基本数据类型都属于T类范畴,如TInt、TReal。T前缀也用于枚举类型。在Symbian中,T类型代替了C++中的结构体。
C类直接或间接地继承了CBase类。C类有两个特点:安全的构造和析构、零值初始化。C类一般使用两级构造函数来完成构造,释放资源通过析构函数完成。初始化时,C类的成员变量都会被赋为零值。C类对象必须在堆内存中分配空间。
R类是访问系统资源的类,也称为资源类。所以也可以说R类实际就是访问系统资源的一个代理,因为在Symbian中,资源由服务器程序进行管理,用户程序需要通过R类对象访问和操作服务器进程管理的系统资源。使用R类之前,要调用诸如Open(),Create()或Initialize()等函数来分配资源和设定句柄成员变量,用完之后,要通过相应的Close()或Reset()函数来释放资源和重置句柄值。否则会有内存泄露。
在Symbian OS中,M类称为混合类,主要为Symbian SDK中的引擎或工具提供对外接口,也可以称为接口类,也就是C++中的纯虚类,所以M类中的成员函数都是虚函数且不需要实现,其主要作用就是提供接口;在Symbian OS中,M类通常定义为回调接口(callback)或监听器接口(observer);
防止内存泄露的简单做法
四种基本的类的的使用各有各的特点,C类和R类的资源是必须释放的,T类可以当成基本类型来使用,M类只是相当于Java语言中的接口。
造成内存泄露的主要是C类和R类,针对这两类,我总结出了几条简单的原则,可以避免大部分的内存泄露问题。
- T类在栈空间内可以随便使用。
- 成员变量不能入清除栈,必须在析构函数里释放。释放时,C类用delete,R类一般用Reset。
- 对成员变量赋值前要先释放其资源并将其赋为空值(R类只需释放)。
- 函数体(准确点说,是作用域)内使用的C类或R类的局部变量时,应该创建后立即压入清除栈中。在退出函数体之前记得出栈并视情况销毁。如返回值不出栈则函数名应该加上“C”后缀。
- 有可能出现异常的函数,如不处理异常则函数名必须加“L”后缀。
——摘自毕业论文