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
|
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 );
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。 |
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
|
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
|
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;
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
|
Growing the Array
SetAtGrow | Sets the value for a given index; grows the array if necessary. void SetAtGrow( int nIndex, ARG_TYPE newElement );
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
|
Add | Adds an element to the end of the array; grows the array if necessary.
int Add( ARG_TYPE newElement );
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
|
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
|
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
|
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 );
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
|
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
|
Operators
operator [] | Sets or gets the element at the specified index. TYPE& operator []( int nIndex );
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();
}