CArray
Class
Supports arrays that are like C arrays, but can dynamically reduce and grow as necessary.
template <class TYPE, class ARG_TYPE = const TYPE&>
class CArray : public CObject
TYPE
Template parameter that specifies the type of objects stored in the array. TYPE
is a parameter that is returned by CArray
.
ARG_TYPE
Template parameter that specifies the argument type that is used to access objects stored in the array. Often a reference to TYPE
. ARG_TYPE
is a parameter that is passed to CArray
.
Name | Description |
---|---|
CArray::CArray |
Constructs an empty array. |
Name | Description |
---|---|
CArray::Add |
Adds an element to the end of the array; grows the array if necessary. |
CArray::Append |
Appends another array to the array; grows the array if necessary |
CArray::Copy |
Copies another array to the array; grows the array if necessary. |
CArray::ElementAt |
Returns a temporary reference to the element pointer within the array. |
CArray::FreeExtra |
Frees all unused memory above the current upper bound. |
CArray::GetAt |
Returns the value at a given index. |
CArray::GetCount |
Gets the number of elements in this array. |
CArray::GetData |
Allows access to elements in the array. Can be NULL . |
CArray::GetSize |
Gets the number of elements in this array. |
CArray::GetUpperBound |
Returns the largest valid index. |
CArray::InsertAt |
Inserts an element (or all the elements in another array) at a specified index. |
CArray::IsEmpty |
Determines whether the array is empty. |
CArray::RemoveAll |
Removes all the elements from this array. |
CArray::RemoveAt |
Removes an element at a specific index. |
CArray::SetAt |
Sets the value for a given index; array not allowed to grow. |
CArray::SetAtGrow |
Sets the value for a given index; grows the array if necessary. |
CArray::SetSize |
Sets the number of elements to be contained in this array. |
Name | Description |
---|---|
operator[] |
Sets or gets the element at the specified index. |
Array indexes always start at position 0. You can decide whether to fix the upper bound or enable the array to expand when you add elements past the current bound. Memory is allocated contiguously to the upper bound, even if some elements are null.
Note
Most methods that resize a CArray
object or add elements to it use memcpy_s
to move elements. This is a problem because memcpy_s
is not compatible with any objects that require the constructor to be called. If the items in the CArray
are not compatible with memcpy_s
, you must create a new CArray
of the appropriate size. You must then use CArray::Copy
and CArray::SetAt
to populate the new array because those methods use an assignment operator instead of memcpy_s
.
As with a C array, the access time for a CArray
indexed element is constant and is independent of the array size.
Tip
Before using an array, use SetSize
to establish its size and allocate memory for it. If you do not use SetSize
, adding elements to your array causes it to be frequently reallocated and copied. Frequent reallocation and copying are inefficient and can fragment memory.
If you need a dump of individual elements in an array, you must set the depth of the CDumpContext
object to 1 or larger.
Certain member functions of this class call global helper functions that must be customized for most uses of the CArray
class. See the topic Collection Class Helpers in the MFC Macros and Globals section.
Array class derivation is like list derivation.
For more information about how to use CArray
, see the article Collections.
CArray
Header: afxtempl.h
Adds a new element to the end of an array, growing the array by 1.
INT_PTR Add(ARG_TYPE newElement);
ARG_TYPE
Template parameter specifying the type of arguments referencing elements in this array.
newElement
The element to be added to this array.
The index of the added element.
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 for CArray::Add
CArray<CPoint, CPoint> ptArray;
CPoint pt(10, 20);
ptArray.Add(pt); // Element 0
ptArray.Add(CPoint(30, 40)); // Element 1
Call this member function to add the contents of one array to the end of another.
INT_PTR Append(const CArray& src);
src
Source of the elements to be appended to an array.
The index of the first appended element.
The arrays must be of the same type.
If necessary, Append
may allocate extra memory to accommodate the elements appended to the array.
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);
Constructs an empty array.
CArray();
The array grows one element at a time.
CArray<CPoint, CPoint> ptArray;
Use this member function to copy the elements of one array to another.
void Copy(const CArray& src);
src
Source of the elements to be copied to an array.
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.
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);
Returns a temporary reference to the specified element within the array.
TYPE& ElementAt(INT_PTR nIndex);
const TYPE& ElementAt(INT_PTR nIndex) const;
nIndex
An integer index that is greater than or equal to 0 and less than or equal to the value returned by GetUpperBound
.
A reference to an array element.
It is used to implement the left-side assignment operator for arrays.
See the example for GetSize
.
Frees any extra memory that was allocated while the array was grown.
void FreeExtra();
This function has no effect on the size or upper bound of the array.
See the example for GetData
.
Returns the array element at the specified index.
TYPE& GetAt(INT_PTR nIndex);
const TYPE& GetAt(INT_PTR nIndex) const;
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 by GetUpperBound
.
The array element currently at this index.
Passing a negative value or a value greater than the value returned by GetUpperBound
will result in a failed assertion.
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 (int i = 0; i <= myArray.GetUpperBound(); i++)
{
pt = myArray.GetAt(i);
pt.x = 0;
myArray.SetAt(i, pt);
}
Returns the number of array elements.
INT_PTR GetCount() const;
The number of items in the array.
Call this method to retrieve the number of elements in the array. Because indexes are zero-based, the size is 1 greater than the largest index. Calling this method will generate the same result as the CArray::GetSize
method.
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 (int i = 0; i < myArray.GetCount(); i++)
{
CPoint &pt = myArray.ElementAt(i);
pt.x = 0;
}
Use this member function to gain direct access to the elements in an array.
const TYPE* GetData() const;
TYPE* GetData();
TYPE
Template parameter specifying the type of the array elements.
A pointer to an array element.
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 calling GetData
; any errors you make directly affect the elements of your array.
CArray<CPoint, CPoint> myArray;
// Allocate memory for at least 32 elements.
myArray.SetSize(32, 128);
// Add elements to the array.
CPoint *pPt = (CPoint *)myArray.GetData();
for (int 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();
#if _DEBUG
afxDump.SetDepth(1);
afxDump << "myArray: " << &myArray << "\n";
#endif
Returns the size of the array.
INT_PTR GetSize() const;
Because indexes are zero-based, the size is 1 greater than the largest index. Calling this method will generate the same result as the CArray::GetCount
method.
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 (int i = 0; i < myArray.GetSize(); i++)
{
CPoint &pt = myArray.ElementAt(i);
pt.x = 0;
}
Returns the current upper bound of this array.
INT_PTR GetUpperBound() const;
Because array indexes are zero-based, this function returns a value 1 less than GetSize
.
The condition GetUpperBound( )
= -1 indicates that the array contains no elements.
See the example for CArray::GetAt
.
The first version of InsertAt
inserts one element (or multiple copies of an element) at a specified index in an array.
void InsertAt(
INT_PTR nIndex,
ARG_TYPE newElement,
INT_PTR nCount = 1);
void InsertAt(
INT_PTR nStartIndex,
CArray* pNewArray);
nIndex
An integer index that may be greater than the value returned by GetUpperBound
.
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 by GetUpperBound
.
pNewArray
Another array that contains elements to be added to this 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 the nStartIndex
position.
The SetAt
function, in contrast, replaces one specified array element and does not shift any elements.
// example for CArray::InsertAt
CArray<CPoint, CPoint> ptArray;
ptArray.Add(CPoint(10, 20)); // Element 0
ptArray.Add(CPoint(30, 40)); // Element 1 (will become element 2)
ptArray.InsertAt(1, CPoint(50, 60)); // New element 1
Determines whether the array is empty.
BOOL IsEmpty() const;
Nonzero if the array contains no elements; otherwise 0.
These subscript operators are a convenient substitute for the SetAt
and GetAt
functions.
TYPE& operator[](int_ptr nindex);
const TYPE& operator[](int_ptr nindex) const;
TYPE
Template parameter specifying the type of elements in this array.
nIndex
Index of the element to be accessed.
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 for const
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.
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 (int i = 0; i <= myArray.GetUpperBound(); i++)
{
myArray[i].x = 0;
}
Relocates data to a new buffer when the array should grow or shrink.
template<class TYPE, class ARG_TYPE>
AFX_INLINE void CArray<TYPE, ARG_TYPE>::RelocateElements(
TYPE* pNewData,
const TYPE* pData,
INT_PTR nCount);
pNewData
A new buffer for the array of elements.
pData
The old array of elements.
nCount
Number of elements in the old array.
pNewData
is always large enough to hold all the pData
elements.
The CArray
implementation uses this method to copy the old data to a new buffer when the array should grow or shrink (when SetSize
or FreeExtra
are called). The default implementation just copies the data.
For arrays in which an element contains a pointer to one of its own members, or another structure contains a pointer to one of the array elements, the pointers are not updated in plain copy. In this case, you can correct pointers by implementing a specialization of RelocateElements
with the relevant types. You are also responsible for data copying.
Removes all the elements from this array.
void RemoveAll();
If the array is already empty, the function still works.
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
Removes one or more elements starting at a specified index in an array.
void RemoveAt(
INT_PTR nIndex,
INT_PTR nCount = 1);
nIndex
An integer index that is greater than or equal to 0 and less than or equal to the value returned by GetUpperBound
.
nCount
The number of elements to remove.
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.
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
Sets the array element at the specified index.
void SetAt(INT_PTR nIndex, ARG_TYPE newElement);
nIndex
An integer index that is greater than or equal to 0 and less than or equal to the value returned by GetUpperBound
.
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.
SetAt
will not cause the array to grow. Use SetAtGrow
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.
See the example for GetAt
.
Sets the array element at the specified index.
void SetAtGrow(INT_PTR nIndex, ARG_TYPE newElement);
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.
The array grows automatically if necessary (that is, the upper bound is adjusted to accommodate the new element).
// example for CArray::SetAtGrow
CArray<CPoint, CPoint> ptArray;
ptArray.Add(CPoint(10, 20)); // Element 0
ptArray.Add(CPoint(30, 40)); // Element 1
// Element 2 deliberately skipped
ptArray.SetAtGrow(3, CPoint(50, 60)); // Element 3
Establishes the size of an empty or existing array; allocates memory if necessary.
void SetSize(
INT_PTR nNewSize,
INT_PTR nGrowBy = -1);
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.
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 use SetSize
, 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 by GetSize
and GetUpperBound
. If the default value is used, MFC allocates memory in a way calculated to avoid memory fragmentation and optimize efficiency for most cases.
See the example for GetData
.
MFC Sample COLLECT
CObject
Class
Hierarchy Chart
CObArray
Class
Collection Class Helpers