CArray Class

来源:互联网 发布:js radio 多选 编辑:程序博客网 时间:2024/06/05 15:31

CArray Class Members

#include <afxtempl.h>

template< classTYPE, classARG_TYPE> class CArray : public CObject

第一个参数为数组元素的类型,如CArray<int,int>caiNum;即caiNum是int数组;如果是构造数据类型如一个结构体、类,并且当这个数据类型存在指针,需要深拷贝的话,那么CArray将会无法工作。所以,我们必须要为这个构造数据类型,提供一个赋值构造函数。
第二个参数为引用类型,有两种选择:
第一种选择与第一个参数类型相同,它意味着数组对象作为参数传递时,传递的是数组对象。
第二种选择是第一个参数类型的引用,它意味着数组对象作为参数传递时,传递的是数组对象的指针。因此,尤其对于较复杂的数组结构类型,推荐使用引用传递,节约内存同时加快程序运行速度,CArray<int,int&>caiNum;。

Construction

CArray

Constructs an empty array.


Attributes

GetSize

Gets the number of elements in this array.

int GetSize( ) const;

Returns the size of the array. Since indexes are zero-based, the size is 1 greater than the largest index.

取得当前数组元素个数.

Example

CArray<CPoint,CPoint> myArray;// Add elements to the array.for (int i=0;i < 10;i++)      myArray.Add( CPoint(i, 2*i) );// Modify all the points in the array.for (i=0;i < myArray.GetSize();i++){   CPoint& pt = myArray.ElementAt(i);   pt.x = 0;}

GetUpperBound

Returns the largest valid index.

int GetUpperBound( ) const;

Returns the current upper bound of this array. Because array indexes are zero-based, this function returns a value 1 less thanGetSize.

The condition GetUpperBound( ) = –1 indicates that the array contains no elements.

最得最大的元素的索引,由于C的数组是从0开始,所以此函数的返回值比GetSize的返回值比小.SetSize

Sets the number of elements to be contained in this array.

void SetSize( int nNewSize, int nGrowBy = -1 );
throw( CMemoryException );

Parameters

nNewSize

The new array size (number of elements). Must be greater than or equal to 0.

nGrowBy

The minimum number of element slots to allocate if a size increase is necessary.

Remarks

Establishes the size of an empty or existing array; allocates memory if necessary.

If the new size is smaller than the old size, then the array is truncated and all unused memory is released.

Use this function to set the size of your array before you begin using the array. If you do not useSetSize, adding elements to your array causes it to be frequently reallocated and copied. Frequent reallocation and copying are inefficient and can fragment memory.

The nGrowBy parameter affects internal memory allocation while the array is growing. Its use never affects the array size as reported byGetSize andGetUpperBound. If the default value is used, MFC allocates memory in a way calculated to avoid memory fragmentation and optimize efficiency for most cases.

设置数组的大小.

在使用一个数组之前,使用SetSize建立它的大小和为它分配内存。如果不使用SetSize,则为数组添加元素就会引起频繁地重新分配和拷贝。频繁地重新分配和拷贝不但没有效率,而且导致内存碎片。

第二个参数设定数组增长时内存分配的大小,缺省值是-1,使用缺省值可以保证内存分配得更合理。

需要特别说明的是,如果使用了SetSize函数,在使用Add函数时Add函数会在数组原来的大小上扩展数组,数组前面的元素全为0。

        int iCount = 0;        CArray<int,int>caiNum;caiNum.SetSize(10);iCount = caiNum.GetSize();cout << "caiNum's size is:" << iCount << endl;caiNum.Add(100);//使用了SetSize10,所以在第11个位置//增加元素100,前面10个元素为0 caiNum.Add(101);        iCount = caiNum.GetSize();cout << "caiNum's size is:" << iCount << endl;cout << caiNum.GetAt(0) << endl;cout << caiNum.GetAt(11) << endl;cout << "==================================" << endl;caiNum.InsertAt(2,200);//在第3个位置增加元素200,后面元素后移         cout << caiNum.GetAt(0) << endl;cout << caiNum.GetAt(11) << endl;cout << caiNum.GetAt(2) << endl;




Operations

FreeExtra

Frees all unused memory above the current upper bound.

void FreeExtra( );

Frees any extra memory that was allocated while the array was grown. This function has no effect on the size or upper bound of the array.

释放未使用的空间.RemoveAll

Removes all the elements from this array.

void RemoveAll( );

Removes all the elements from this array. If the array is already empty, the function still works.
删除所有的元素.

Example

CArray<CPoint,CPoint> myArray;// Add elements to the array.for (int i=0;i < 10;i++)   myArray.Add( CPoint(i, 2*i) );myArray.RemoveAll();#ifdef _DEBUG    afxDump.SetDepth( 1 );    afxDump << "myArray: " << &myArray << "\n";#endif


Element Access

GetAt

Returns the value at a given index.

TYPE GetAt( int nIndex ) const;

Return Value

The array element currently at this index.

Parameters

TYPE

Template parameter specifying the type of the array elements.

nIndex

An integer index that is greater than or equal to 0 and less than or equal to the value returned byGetUpperBound.

Remarks

Returns the array element at the specified index.

Note   Passing a negative value or a value greater than the value returned byGetUpperBound will result in a failed assertion.

根据索引(参数)取得某个数组元素的值.

Example

CArray<CPoint,CPoint> myArray;CPoint pt;// Add elements to the array.for (int i=0;i < 10;i++)   myArray.Add( CPoint(i, 2*i) );// Modify all the points in the array.for (i=0;i <= myArray.GetUpperBound();i++){   pt = myArray.GetAt(i);   pt.x = 0;   myArray.SetAt(i, pt);}

SetAt

Sets the value for a given index; array not allowed to grow.

void SetAt( int nIndex, ARG_TYPE newElement );

Parameters

nIndex

An integer index that is greater than or equal to 0 and less than or equal to the value returned byGetUpperBound.

ARG_TYPE

Template parameter specifying the type of arguments used for referencing array elements.

newElement

The new element value to be stored at the specified position.

Remarks

Sets the array element at the specified index. SetAt will not cause the array to grow. UseSetAtGrow if you want the array to grow automatically.

You must ensure that your index value represents a valid position in the array. If it is out of bounds, then the Debug version of the library asserts.

将第nIndex的元素的值设置成newElement.ElementAt

Returns a temporary reference to the element pointer within the array.

TYPE& ElementAt( int nIndex );

Return Value

A reference to an array element.

Parameters

TYPE

Template parameter specifying the type of elements in the array.

nIndex

An integer index that is greater than or equal to 0 and less than or equal to the value returned byGetUpperBound.

Remarks

Returns a temporary reference to the specified element within the array. It is used to implement the left-side assignment operator for arrays.

取得第nIndex个元素的引用.GetData

Allows access to elements in the array. Can be NULL.

const TYPE* GetData( ) const;
TYPE* GetData( );

Return Value

A pointer to an array element.

Parameters

TYPE

Template parameter specifying the type of the array elements.

Remarks

Use this member function to gain direct access to the elements in an array. If no elements are available,GetData returns a null value.

While direct access to the elements of an array can help you work more quickly, use caution when callingGetData; any errors you make directly affect the elements of your array.

取得静态数组指针.

Example

CArray<CPoint,CPoint> myArray;int i;// Allocate memory for at least 32 elements.myArray.SetSize(32, 128);// Add elements to the array.CPoint* pPt = (CPoint*) myArray.GetData();for (i=0;i < 32;i++,pPt++)   *pPt = CPoint(i, 2*i);// Only keep first 5 elements and free extra (unused) bytes.myArray.SetSize(5, 128);myArray.FreeExtra();#ifdef _DEBUG    afxDump.SetDepth( 1 );    afxDump << "myArray: " << &myArray << "\n";#endif


Growing the Array

SetAtGrow

  Sets the value for a given index; grows the array if necessary.

void SetAtGrow( int nIndex, ARG_TYPE newElement );
throw( CMemoryException );

Parameters

nIndex

An integer index that is greater than or equal to 0.

ARG_TYPE

Template parameter specifying the type of elements in the array.

newElement

The element to be added to this array. A NULL value is allowed.

Remarks

Sets the array element at the specified index. The array grows automatically if necessary (that is, the upper bound is adjusted to accommodate the new element).

将第nIndex个元素设置成newElement,如果数组元素不够,会增加空间.

Example

// example for CArray::SetAtGrowCArray<CPoint,CPoint> ptArray;ptArray.Add(CPoint(10,20));   // Element 0ptArray.Add(CPoint(30,40));   // Element 1                     // Element 2 deliberately skippedptArray.SetAtGrow(3, CPoint(50,60));   // Element 3

Add

Adds an element to the end of the array; grows the array if necessary.

int Add( ARG_TYPE newElement );
throw( CMemoryException );

Return Value

The index of the added element.

Parameters

ARG_TYPE

Template parameter specifying the type of arguments referencing elements in this array.

newElement

The element to be added to this array.

Remarks

Adds a new element to the end of an array, growing the array by 1. If SetSize has been used with an nGrowBy value greater than 1, then extra memory may be allocated. However, the upper bound will increase by only 1.

向数组的结尾添加一个元素;如果必要的话,在数组的结尾添加一个元素;如果必要的话,可以在数组中添加数组。

Example

// example for CArray::AddCArray<CPoint,CPoint> ptArray;CPoint pt(10,20);ptArray.Add(pt);             // Element 0ptArray.Add(CPoint(30,40));  // Element 1

Append

Appends another array to the array; grows the array if necessary.

int Append( const CArray& src );

Return Value

The index of the first appended element.

Parameters

src

Source of the elements to be appended to an array.

Remarks

Call this member function to add the contents of one array to the end of another. The arrays must be of the same type.

If necessary, Append may allocate extra memory to accommodate the elements appended to the array.

将另一个数组追加过来.

Example

CArray<CPoint,CPoint> myArray1, myArray2;// Add elements to the second array.myArray2.Add( CPoint(11, 22) );myArray2.Add( CPoint(12, 42) );// Add elements to the first array and also append the second array.myArray1.Add( CPoint(1, 2) );myArray1.Append( myArray2 );

Copy

Copies another array to the array; grows the array if necessary.

void Copy( const CArray& src );

Parameters

src

Source of the elements to be copied to an array.

Remarks

Use this member function to copy the elements of one array to another.

Call this member function to overwrite the elements of one array with the elements of another array.

Copy does not free memory; however, if necessary, Copy may allocate extra memory to accommodate the elements copied to the array.

复制数组,已经内容将会被覆盖.

Example

CArray<CPoint,CPoint> myArray1, myArray2;// Add elements to the second array.myArray2.Add( CPoint(11, 22) );myArray2.Add( CPoint(12, 42) );// Copy the elements from the second array to the first.myArray1.Copy( myArray2 );


Insertion/Removal

InsertAt

Inserts an element (or all the elements in another array) at a specified index.

void InsertAt( int nIndex, ARG_TYPE newElement, int nCount = 1 );
throw( CMemoryException );
void InsertAt( int nStartIndex, CArray* pNewArray );
throw( CMemoryException );

Parameters

nIndex

An integer index that may be greater than the value returned byGetUpperBound.

ARG_TYPE

Template parameter specifying the type of elements in this array.

newElement

The element to be placed in this array.

nCount

The number of times this element should be inserted (defaults to 1).

nStartIndex

An integer index that may be greater than the value returned byGetUpperBound.

pNewArray

Another array that contains elements to be added to this array.

Remarks

The first version of InsertAt inserts one element (or multiple copies of an element) at a specified index in an array. In the process, it shifts up (by incrementing the index) the existing element at this index, and it shifts up all the elements above it.

The second version inserts all the elements from another CArray collection, starting at thenStartIndex position.

The SetAt function, in contrast, replaces one specified array element and does not shift any elements.

插入一个元素(或另一个数组)到数组.

该函数根据元素序号值插入相应元素值,后面的元素会自动后移。

Example

// example for CArray::InsertAtCArray<CPoint,CPoint> ptArray;ptArray.Add(CPoint(10,20));   // Element 0ptArray.Add(CPoint(30,40));   // Element 1 (will become element 2)ptArray.InsertAt(1, CPoint(50,60));   // New element 1

RemoveAt

Removes an element at a specific index.

void RemoveAt( int nIndex, int nCount = 1 );

Parameters

nIndex

An integer index that is greater than or equal to 0 and less than or equal to the value returned byGetUpperBound.

nCount

The number of elements to remove.

Remarks

Removes one or more elements starting at a specified index in an array. In the process, it shifts down all the elements above the removed element(s). It decrements the upper bound of the array but does not free memory.

If you try to remove more elements than are contained in the array above the removal point, then the Debug version of the library asserts. 

删除另一个元素.

RemoveAt只有一个参数,即元素序号值。该函数根据元素序号值删除相应元素值,后面的元素会自动前移。

Example

CArray<CPoint,CPoint> myArray;// Add elements to the array.for (int i=0;i < 10;i++)   myArray.Add( CPoint(i, 2*i) );myArray.RemoveAt(5);#ifdef _DEBUG    afxDump.SetDepth( 1 );    afxDump << "myArray: " << &myArray << "\n";#endif


Operators

operator []

Sets or gets the element at the specified index.

TYPE& operator []( int nIndex );
TYPE operator []( int nIndex ) const;

Parameters

TYPE

Template parameter specifying the type of elements in this array.

nIndex

Index of the element to be accessed.

Remarks

These subscript operators are a convenient substitute for the SetAt and GetAt functions.

The first operator, called for arrays that are not const, may be used on either the right (r-value) or the left (l-value) of an assignment statement. The second, called forconst arrays, may be used only on the right.

The Debug version of the library asserts if the subscript (either on the left or right side of an assignment statement) is out of bounds.

通过索引设置或取得另一个元素.
Example

CArray<CPoint,CPoint> myArray;// Add elements to the array.for (int i=0;i < 10;i++)      myArray.Add( CPoint(i, 2*i) );// Modify all the points in the array.for (i=0;i <= myArray.GetUpperBound();i++){   myArray[i].x = 0;}


如下是CArray详细应用,参考地址:http://www.bianceng.cn/Programming/vc/201306/36636.htm、

http://yiluohuanghun.blog.51cto.com/3407300/1118301

一、获得返回值:

可以作为函数的一个参数

比如定义fun(CArray<int, int &> &array)

采用引用类型,就可以直接使用

二、作为函数参数:

#include<Afxtempl.h>    //定义函数。   void ansnode(int num,CArray<double,double&> m_adX, CArray<double,double&> m_adY, CArray<double,double&> m_adZ);
函数体:

void ansysdata::ansnode(int num,CArray<double,double&> *m_adX, CArray<double,double&> *m_adY, CArray<double,double&> *m_adZ)   {          double x, y,z; int i;          fstream infilex;          fstream infiley;          fstream infilez;          infilex.open("d:/intface/M_ADX.TXT.txt",ios::in);           infiley.open("d:/intface/M_ADX.TXT.txt",ios::in);           infilez.open("d:/intface/M_ADX.TXT.txt",ios::in);           for (i=0;i<num;i++)          {              infilex>>x;              infiley>>y;              infilez>>z;              m_adX.Add(x);              m_adY.Add(y);               m_adZ.Add(z);          }          fstream outfilex;          fstream outfiley;          fstream outfilez;          outfilex.open("d:/intface/M_ADX1.TXT.txt",ios::in);           outfiley.open("d:/intface/M_ADX2.TXT.txt",ios::in);           outfilez.open("d:/intface/M_ADX3.TXT.txt",ios::in);           for (i=0;i<num;i++)         {             outfilex<<m_adX.GetAt(i)<<endl;              outfiley<<m_adY.GetAt(i)<<endl;             outfilez<<m_adZ.GetAt(i)<<endl;          }   }
三、CArray结构体中的应用
struct DriverItem    {         CString strDriverName;         CString strProductDescribe;         CString strTBLFileName;    };    struct ControlItem    {          CString strControlType;          CArray <DriverItem,DriverItem&> DriverArray;    };

四、CArray的简单说明

CArray <Object,Object> Var1;

CArray <Object,Object&> Var2;

第一个参数是CArray的返回的参数,第二个参数是传递给CArray的参数。即,当使用第二种形式定义Carray数组时,使用Add()时是一个引用类型的参数。

五、转帖

最近一直在编写一个绘图程序,为了保存多个double型点坐标,这里我采用了定义集合类CArray<TYPE, ARG_TYPE>CPointDArray来保存多点,然后定义坐标转换函数ConvertToXYs(CPointDArray,long* xy),将double坐标转换为long型坐标,这是就出现几种常见错误,"CPointDArray缺少构造函数,或者是拷贝构造函数不存在”,‘不能将参数 1 从“CArray<TYPE,ARG_TYPE>”转换为“CArray<TYPE,ARG_TYPE>”,从这两个问题入手,举例说明问题。

下面代码为我修改多次后总结的一个实例,照着此方法可以推广:

1.建立一个VC6工程 ,在CTestView中,添加一个OnLButtonDown,在这里实现点的绘制。

2.在CTestView.h中,自定义double类型的点类以及数组

class CPointD   {   public:       double x; //longtitude       double y; //latitude       CPointD()       {           x =0;          y=0;        };        CPointD(const double dx,double dy)       {           x = dx;           y = dy;        };        CPointD(const CPointD& pnt)       {            x = pnt.x;            y = pnt.y;        };        CPointD& operator=(const CPointD& rhs)        {            if (this == &rhs)            {                return *this;             }             x = rhs.x;             y = rhs.y;             return *this;        }   };//double 型指针链表   typedef CArray<CPointD,CPointD>CPointDArray; //double 型数组   typedef CArray<POINT,POINT&>LPointArray;//long型数组
      注意这里CArray<CPointD,CPointD>可以用CArray<CPointD*,CPointD*>,实验证明没有问题。

3.在视图类CTestView定义全局变量CPointDArray plist;

定义函数void ConvToXYs(const CPointDArray &alist, LPointArray& llist);//&alist为常应用,保存函数中不修改数据,&llist是alist转

//换成long后的数组。这里就是出现上述常见问题的症结。

下面为实现部分

void CTestLineView::ConvToXYs(const CPointDArray &alist, LPointArray& llist)   {        if (alist.GetSize()>0)        {             llist.RemoveAll();             int i ;             int n = alist.GetSize();             llist.SetSize(n);                     double jing, wei;             for(i=0;i<n;i++)             {                  CPointD p = alist.GetAt(i);                  jing = p.x;                  wei = p.y;                  llist[i].x = (long)(jing+0.5);//这是关键步骤,可以当数组用                  llist[i].y = (long)(wei+0.5);//             }
4.在鼠标左键事件中实现绘制:
void CTestLineView::OnLButtonDown(UINT nFlags, CPoint point)    {                   CClientDC pDC(this); try       {                CPen* pOldPen = (CPen*)pDC.SelectStockObject(2);                       for (int i=0;i<10;i++)              {                  // CPointD *p=new CPointD(i*3.5f,i*5.5f);                  plist.Add(CPointD(i*3.5f,i*5.5f));               }                        LPointArray longpoints;               ConvToXYs(plist,longpoints);               pDC.Polyline(longpoints.GetData(),plist.GetSize());              CString str;              str.Format("%d",longpoints.GetSize());              AfxMessageBox(str,MB_OK);              // Restore the original device context objects.                     pDC.SelectObject(pOldPen);            }   catch (CException* e)   {       LPTSTR lp="" ;       e->GetErrorMessage(lp,250);       AfxMessageBox(lp);   }           CView::OnLButtonDown(nFlags, point);   }
最后在~CTestLineView中清除plist。
CTestLineView::~CTestLineView()   {       if(plist.GetSize())       plist.RemoveAll();   }



0 0