SHARE & TOP

我会变成童话里,你爱的那个天使

原创 Symbian学习笔记(9):数组收藏

新一篇: 打造自己的Carbide C++工程向导和模板

数组是一个很基本的东西了,但是在Symbian中也做了比较人性化的封装,让我们可以省却不少代码,当然也让我们这些新手有点摸不着头脑。

三个类比较实用,需要掌握:TFixedArray、RArray和RPointerArray。

TFixedArray
它是最类似于我们平时使用的数组,从概念上或者从使用上都非常类似。
//声明
TFixedArray<TGridCell,81> iGrid;

//使用
void CSuDoScAppView::InitGrid()
{
    
for(TInt i=0;i<81;i++)
    
{    
        
if(iCurQs->data[i]==0)
        
{
            iGrid[i].state
=TGridCell::ECSTATE_EMPTY;
        }

        
else
        
{
            iGrid[i].state
=TGridCell::ECSTATE_FIXED;
        }

        iGrid[i].value
=iCurQs->data[i];
        
for(TInt j=0;j<9;j++) iGrid[i].tries[j]=0;
    }

    
if(iHeart!=NULL){
        iHeart
->Cancel();
        iTime
=0;
        iHeart
->Start(ETwelveOClock,this);
    }

}

把它当成普通的数组来用就OK了,一般也就是用它重载的运算符[]和Count(),不需new也不需要delete。

RArray
从名字上看它以R开头,至少说明一点,在使用完后我们需要将它Close掉。在使用上也比较简单,类似于ArrayList吧。比如下面代码:
//声明
RArray<TQuestion>    iList;    

//使用
void CSuDoScAppCtrol::LoadQuestions()
{
    RFile file;
    TBuf8
<4> bufC4;
    TBuf8
<81> bufC81;
    
    
if(KErrNone==file.Open(iFs,KTiDataFile,EFileRead))
    
{
        file.Read(bufC4,
4);        
        TUint len
=((TUint)bufC4[3]<<24)+((TUint)bufC4[2]<<16)+((TUint)bufC4[1]<<8)+(TUint)bufC4[0];
        
        
for(int i=0;i<len;i++){
            TQuestion ti;
            bufC4.FillZ();
            file.Read(bufC4,
4);
            ti.code
=((TUint)bufC4[3]<<24)+((TUint)bufC4[2]<<16)+((TUint)bufC4[1]<<8)+(TUint)bufC4[0];
            bufC4.FillZ();
            file.Read(bufC4,
4);
            ti.time
=0;
            bufC81.FillZ();
            file.Read(bufC81,
81);
            
for(TInt i=0;i<81;i++)ti.data[i]=bufC81[i];
            iList.Append(ti);            
        }
        
        file.Close();        
    }

    
}

除了在析构函数中需要iList.Close()以外,事先不需要做什么初始化工作,一个个的Append进去就可以了。它也重载了运算符[],可以简单地访问其中的元素。

另外,RArray还提供了插入、查找、排序等功能。

RPointerArray
名字上说明它与指针有关,的确它与RArray的差别在于它不是保存对象的副本而是保存对象的指针。所以,使用上需要自己负责将元素删除。
//声明
RPointerArray<CFbsBitmap> iThumbNormal;

//使用
for(TInt i=0,j=0;i<9;i++,j+=2){
        CFbsBitmap 
* b=NULL;
        CFbsBitmap 
* c=NULL;
        AknIconUtils::CreateIconL(b,c,iMFileName,EMbmSudoscY1
+j,EMbmSudoscY1+j+1);        
        AknIconUtils::SetSize(b, TSize(
2222));
        AknIconUtils::SetSize(c, TSize(
2222));
        iThumbNormal.AppendL(b);
        iThumbNormalMask.AppendL(c);
    }


//删除
for(TInt i=0;i<9;i++){
        delete iThumbNormal[i];
        delete iThumbNormalMask[i];

}

iThumbNormal.Close();

此外,虽然SDK中我们也看到许多CDesXXXX的数组类,但是我觉得上面三个类应该可以应付我们大多数的场合了。

[补充@2008-3-24]
因为上面三个数组是平台缓冲的,所以并不适合在插入较多的场合,如果你的数组经常插入元素,还是建议使用CArrayXXXXXSeg之类的数组类来实现。

[补充@2008-3-25]
谢谢bluepac网友的讨论,现在我补充说明一下:

虽然我觉得上述三个数组类可以解决我们大多数的应用场合,但并非它们就是万能的了。

Symbian不提倡我们直接使用C++数组,就象不提倡我们直接使用int,char一样,它提供了大量的有益的替代类。我们只需要记住:既然在Symbian平台上开发,就要听话哦。反正我从小都一直是听话的孩子。

还有两类数组,一类是描述符作为元素的CDesCXXX or CPtrCXXX。很好理解它们的元素都是描述符罢了,只是注意它的名称后面有一个Flat或者Seg,表示是平面(连续空间、访问效率高)还是分段(非连续空间、适于插入较多的场合)。

另一类就是CArrayXXX之类的动态数组了,它们也相当重要。与描述符数组不同,它们用模板声明元素类型。
CArrayFixFlat<class T> or CArrayFixSeg<class T>,名字中的Fix则 要求元素是定长的对象,可以是T类或者C类。
CArrayPtrFlat<class T> or CArrayPtrSeg<class T>,因为是指针就无所谓元素要求定长了。

而RArray<class T>其实也有同样的要求是定长对象,其实很好理解,除了用指针以外,数组怎么都要求是定长对象放进去。

再次感谢bluepac对我的帮助。

发表于 @ 2008年03月21日 17:14:00|评论(loading...)|编辑

旧一篇: Symbian学习笔记(8):再尝试着做一个数独游戏

评论

#bluepac 发表于2008-03-24 14:37:28  IP: 58.33.231.*
RPointerArray 和 RArray 区别不仅在于指针吧 !
如果你使用RPointerArray,那么它的元素一定是要从CBase 继承的 , 你用的CFbsBitmap 就是从CBase 继承
2008-03-24 15:29:36作者回复
谢谢,你说的对。<br />我的意思是:<br />因为RArray是将对象复制一份保存,所以它的元素可以是T类型或者C类型。<br />但是RPointerArray因为只保存指针,所以它的元素内容肯定是在堆里,所以它的元素肯定是C类型。<br />所以它的根本区别在于RPointerArray是保存指针的。<br /><br /><br />
#bluepac 发表于2008-03-24 16:28:33  IP: 58.33.231.*

官方有两句话:
1.Note that using C++ arrays of CBase-derived types is not recommended, as objects in the array will not be zero-initialised (as there is no operator new[] member). You should use an array class such as RPointerArray instead for arrays of CBase-derived types.
2.RArray ---A simple and efficient array of fixed length objects

我觉得RArray 的element 是C-class时,还是注意objects 是否为fixed length
而T-class 是这样解释的:value classes, that do not own any external object

:)
2008-03-24 16:53:35作者回复
不好意思,我觉得你理解有偏差。你说的文档中讨论的不是RArray与RPointerArray的区别,它说的C++ array of CBase-derived 是说的那些CArrayXXXX之类的东西。
#bluepac 发表于2008-03-24 16:51:39  IP: 58.33.231.*
还有CDesCArray 以及派生的两个类CDesCArrayFlat、CDesCArraySeg 是用于 Descriptors Arrays。
虽然说也属于Array,但是呢,它从CDesCArray继承的了丰富的方法
所以呢,CDes.... 适用的Descriptors Arrays 应用还是比较多滴

PS: 我是专挑LZ 的刺儿啊,哈哈
2008-03-24 16:57:40作者回复
谢谢你挑刺。这是学习笔记。我又不是什么高手,只是新手罢了。的确CArrayXXXX之类的东西也很重要只是R开头的两个从效率上建议使用罢了。
#bluepac 发表于2008-03-24 17:48:34  IP: 58.33.231.*
“它说的C++ array of CBase-derived 是说的那些CArrayXXXX之类的东西。”
是这样的吗?我不同意
CArrayXXXX都是从CBase 继承的,而C-class in symbian 有一个共同的特点:Initialisation of the CBase derived object to binary zeroes through a specific CBase::operator new() - this means that members, whose initial value should be zero, do not have to be initialised in the constructor.

所以这个"C++ array of CBase-derived“ 应该类似如下的定义
class CMyclass ;
CMyclass myclass<6>;
当然symbian 中不建议使用c++ array 。
CArrayXXXX 不等于 C++ array of CBase-derived。
CArrayXXXX和RArray/RPointerArray 共同构成了一个强大的Dynamic Arrays。
(相互切磋,共同进步)
2008-03-25 10:32:01作者回复
谢谢,你说的对。
发表评论  


当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
Csdn Blog version 3.1a
Copyright © sharetop