序列类型的映射

From Apache OpenOffice Wiki
Jump to: navigation, search



IDL 序列被映射成:

 template< class t >
 com::sun::star::uno::Sequence< t > 

序列类是对在堆上分配的引用计数句柄的引用。


序列遵循“修改时复制”策略。如果打算修改某个序列,则检查该序列的引用计数是否为 1。如果为 1,就会直接修改该引用,否则就创建该序列的一个副本,副本的引用计数为 1。


可以将一个任意的 UNO 类型作为元素类型来创建一个序列,但不要使用非 UNO 类型。构造、析构和比较时需要类型库提供的完整反射数据。


您可以构造一个具有初始元素数目的序列。每个元素都是默认构造的。

 {
     // create an integer sequence with 3 elements,
     // elements default to zero.
     Sequence< sal_Int32 > seqInt( 3 );
     
     // get a read/write array pointer (this method checks for
     // the refcount and does a copy on demand).
     sal_Int32 *pArray = seqInt.getArray();
     
     // if you know, that the refocunt is one
     // as in this case, where the sequence has just been
     // constructed, you could avoid the check,
     // which is a C-call overhead,
     // by writing sal_Int32 *pArray = (sal_Int32*) seqInt.getConstArray();
     
     // modify the members
     pArray[0] = 4;
     pArray[1] = 5;
     pArray[2] = 3;
 }


您也可以使用一个不同的构造函数,通过一个同类型的数组来初始化序列。新序列是在堆中进行分配的,并且所有元素是从数据源中复制的。

 {
     sal_Int32 sourceArray[3] = {3,5,3};
 
     // result is the same as above, but we initialize from a buffer.
     Sequence< sal_Int32 > seqInt( sourceArray , 3 );
 }


也可以将结构之类的复杂 UNO 类型存储在序列内:

 {
     // construct a sequence of Property structs,
     // the structs are default constructed
     Sequence< Property > seqProperty(2);
     seqProperty[0].Name = OUString::createFromAscii( "A" );
     seqProperty[0].Handle = 0;
     seqProperty[1].Name = OUString::createFromAscii( "B" );
     seqProperty[1].Handle = 1;
     
     // copy construct the sequence (The refcount is raised)
     Sequence< Property > seqProperty2 = seqProperty;
     
     // access a sequence
     for( sal_Int32 i = 0 ; i < seqProperty.getLength() ; i ++ )
     {
         // Please NOTE : seqProperty.getArray() would also work, but 
         // it is more expensive, because a
         // unnessecary copy construction
         // of the sequence takes place.
         printf( "%d\n" , seqProperty.getConstArray()[i].Handle );
     }
 }


使用 realloc() 方法可以更改序列大小,该方法将新的元素数目作为参数。例如:

 // construct an empty sequence
 Sequence < Any > anySequence;
 
 // get your enumeration from somewhere
 Reference< XEnumeration > rEnum = ...;
 
 // iterate over the enumeration
 while( rEnum->hasMoreElements() )
 {
     anySequence.realloc( anySequence.getLength() + 1 );
     anySequence[anySequence.getLength()-1] = rEnum->nextElement();
 }

上面的代码所示为如何将一个枚举转换成一个序列,它使用了一种低效的方法。realloc() 在序列末尾以默认方式构造一个新元素。如果序列因 realloc 而收缩,则末尾处的元素会被破坏。


序列仅作为传输容器,因此缺乏插入和删除元素的有效方法。将 C++ 标准模板库矢量用作中间容器来处理元素列表,并最终将元素复制到序列中。


某个特定类型的序列是完全支持的 UNO 类型。也可以有包含序列的序列。这与多维数组相似,不同的是每行的长度可以不同。例如:

 {
     sal_Int32 a[ ] = { 1,2,3 }, b[] = {4,5,6}, c[] = {7,8,9,10};
     Sequence< Sequence< sal_Int32 > > aaSeq ( 3 );
     aaSeq[0] = Sequence< sal_Int32 >( a , 3 );
     aaSeq[1] = Sequence< sal_Int32 >( b , 3 );
     aaSeq[2] = Sequence< sal_Int32 >( c , 4 );
 }

是序列< sal_Int32>的一个有效序列。


com::sun::star::uno::Sequence 的最大长度是有限的,因此,如果在 C++ 语言绑定的环境中使用的 UNO 序列太长将会出错。


Content on this page is licensed under the Public Documentation License (PDL).
Personal tools
In other languages