次の方法で共有


CArray クラス

C 配列のような配列をサポートしますが、必要に応じて動的に減らして拡張できます。

構文

template <class TYPE, class ARG_TYPE = const TYPE&>
class CArray : public CObject

パラメーター

TYPE
配列に格納されているオブジェクトの型を指定するテンプレート パラメーター。 TYPE は、 CArrayによって返されるパラメーターです。

ARG_TYPE
配列に格納されているオブジェクトにアクセスするために使用される引数の型を指定するテンプレート パラメーター。 多くの場合、 TYPEへの参照です。 ARG_TYPE は、 CArrayに渡されるパラメーターです。

メンバー

パブリック コンストラクター

名前 説明
CArray::CArray 空の配列を生成します。

パブリック メソッド

名前 説明
CArray::Add 配列の末尾に要素を追加します。必要に応じて、配列を大きくします。
CArray::Append 配列に別の配列を追加します。必要に応じて配列を拡大する
CArray::Copy 配列に別の配列をコピーします。必要に応じて、配列を大きくします。
CArray::ElementAt 配列内の要素ポインターへの一時的な参照を返します。
CArray::FreeExtra 現在の上限を超えている未使用のメモリをすべて解放します。
CArray::GetAt 指定されたインデックス位置にある値を返します。
CArray::GetCount この配列内の要素の数を取得します。
CArray::GetData 配列内の要素へのアクセスを許可します。 NULL の可能性があります。
CArray::GetSize この配列内の要素の数を取得します。
CArray::GetUpperBound 有効な最大のインデックスを返します。
CArray::InsertAt 指定されたインデックス位置に要素 (または別の配列内のすべての要素) を挿入します。
CArray::IsEmpty 配列が空かどうかを判断します。
CArray::RemoveAll この配列からすべての要素を削除します。
CArray::RemoveAt 特定のインデックス位置にある要素を削除します。
CArray::SetAt 指定されたインデックスの値を設定します。配列は大きくできません。
CArray::SetAtGrow 指定されたインデックスの値を設定します。必要に応じて、配列を大きくします。
CArray::SetSize この配列に含まれる要素の数を設定します。

パブリック演算子

名前 説明
operator[] 指定されたインデックス位置にある要素を設定または取得します。

解説

配列インデックスは常に位置 0 から始まります。 現在の境界を超えて要素を追加するときに、上限を修正するか、配列を展開するかを決定できます。 一部の要素が null の場合でも、メモリは上限に連続して割り当てられます。

Note

CArray オブジェクトのサイズを変更したり要素を追加したりするほとんどのメソッドは、memcpy_sを使用して要素を移動します。 memcpy_sはコンストラクターを呼び出す必要があるオブジェクトと互換性がないため、これは問題です。 CArray内の項目がmemcpy_sと互換性がない場合は、適切なサイズの新しいCArrayを作成する必要があります。 これらのメソッドはmemcpy_sの代わりに代入演算子を使用するため、新しい配列を設定するには、CArray::CopyCArray::SetAtを使用する必要があります。

C 配列と同様に、 CArray インデックス付き要素のアクセス時間は定数であり、配列サイズに依存しません。

ヒント

配列を使用する前に、SetSize を使用してそのサイズを設定し、メモリを割り当てます。 SetSize を使用しない場合、配列に要素を追加すると、配列の再割り当てとコピーが頻繁に発生します。 頻繁な再割り当てとコピーは非効率であり、メモリが断片化される可能性があります。

配列内の個々の要素のダンプが必要な場合は、 CDumpContext オブジェクトの深さを 1 以上に設定する必要があります。

このクラスの特定のメンバー関数は、 CArray クラスのほとんどの用途に合わせてカスタマイズする必要があるグローバル ヘルパー関数を呼び出します。 「MFC マクロとグローバル」セクションのトピック「 Collection クラス ヘルパー を参照してください。

配列クラスの派生は、リストの派生に似ています。

CArrayの使用方法の詳細については、Collectionsに関する記事を参照してください。

継承階層

CObject

CArray

要件

ヘッダー: afxtempl.h

CArray::Add

配列の末尾に新しい要素を追加し、配列を 1 ずつ増やします。

INT_PTR Add(ARG_TYPE newElement);

パラメーター

ARG_TYPE
この配列内の要素を参照する引数の型を指定するテンプレート パラメーター。

newElement
この配列に追加する要素。

戻り値

追加された要素のインデックス。

解説

SetSizeが 1 より大きいnGrowBy値で使用されている場合は、追加のメモリが割り当てられる可能性があります。 ただし、上限は 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

CArray::Append

このメンバー関数を呼び出して、ある配列の内容を別の配列の末尾に追加します。

INT_PTR Append(const CArray& src);

パラメーター

src
配列に追加する要素のソース。

戻り値

最初に追加された要素のインデックス。

解説

配列は同じ型である必要があります。

必要に応じて、 Append は、配列に追加された要素に対応するために追加のメモリを割り当てることができます。

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);

CArray::CArray

空の配列を生成します。

CArray();

解説

配列は一度に 1 つの要素を拡大します。

CArray<CPoint, CPoint> ptArray;

CArray::Copy

このメンバー関数を使用して、ある配列の要素を別の配列にコピーします。

void Copy(const CArray& src);

パラメーター

src
配列にコピーする要素のソース。

解説

このメンバー関数を呼び出して、ある配列の要素を別の配列の要素で上書きします。

Copy はメモリを解放しません。ただし、必要に応じて、 Copy は配列にコピーされた要素を格納するために追加のメモリを割り当てることができます。

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);

CArray::ElementAt

配列内の指定した要素への一時的な参照を返します。

TYPE& ElementAt(INT_PTR nIndex);
const TYPE& ElementAt(INT_PTR nIndex) const;

パラメーター

nIndex
0 以上で、 GetUpperBoundによって返される値以下の整数インデックス。

戻り値

配列要素への参照。

解説

配列の左側の代入演算子を実装するために使用されます。

GetSize の例を参照してください。

CArray::FreeExtra

配列の拡大中に割り当てられた追加のメモリを解放します。

void FreeExtra();

解説

この関数は、配列のサイズまたは上限には影響しません。

GetData の例を参照してください。

CArray::GetAt

指定したインデックス位置にある配列要素を返します。

TYPE& GetAt(INT_PTR nIndex);
const TYPE& GetAt(INT_PTR nIndex) const;

パラメーター

TYPE
配列要素の型を指定するテンプレート パラメーター。

nIndex
0 以上で、 GetUpperBoundによって返される値以下の整数インデックス。

戻り値

現在このインデックスにある配列要素。

解説

負の値または GetUpperBound によって返される値より大きい値を渡すと、アサーションが失敗します。

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);
}

CArray::GetCount

配列要素の数を返します。

INT_PTR GetCount() const;

戻り値

配列内の項目の数。

解説

配列内の要素の数を取得するには、このメソッドを呼び出します。 インデックスは 0 から始まるため、サイズは最大インデックスより 1 大きくなります。 このメソッドを呼び出すと、 CArray::GetSize メソッドと同じ結果が生成されます。

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;
}

CArray::GetData

配列内の要素に直接アクセスするには、このメンバー関数を使用します。

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

パラメーター

TYPE
配列要素の型を指定するテンプレート パラメーター。

戻り値

配列要素へのポインター。

解説

使用可能な要素がない場合、 GetData は null 値を返します。

配列の要素への直接アクセスは、より迅速に作業するのに役立ちますが、 GetDataを呼び出すときは注意が必要です。エラーが発生した場合は、配列の要素に直接影響します。

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

CArray::GetSize

配列のサイズを返します。

INT_PTR GetSize() const;

解説

インデックスは 0 から始まるため、サイズは最大インデックスより 1 大きくなります。 このメソッドを呼び出すと、 CArray::GetCount メソッドと同じ結果が生成されます。

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;
}

CArray::GetUpperBound

この配列の現在の上限を返します。

INT_PTR GetUpperBound() const;

解説

配列インデックスは 0 から始まるため、この関数は GetSize より 1 未満の値を返します。

条件 GetUpperBound( ) = -1 は、配列に要素が含まれていることを示します。

CArray::GetAt の例を参照してください。

CArray::InsertAt

InsertAtの最初のバージョンでは、配列内の指定したインデックスに 1 つの要素 (または要素の複数のコピー) が挿入されます。

void InsertAt(
    INT_PTR nIndex,
    ARG_TYPE newElement,
    INT_PTR nCount = 1);

void InsertAt(
    INT_PTR nStartIndex,
    CArray* pNewArray);

パラメーター

nIndex
GetUpperBoundによって返される値より大きい可能性がある整数インデックス。

ARG_TYPE
この配列内の要素の型を指定するテンプレート パラメーター。

newElement
この配列に配置する要素。

nCount
この要素を挿入する回数 (既定値は 1)。

nStartIndex
GetUpperBoundによって返される値より大きい可能性がある整数インデックス。

pNewArray
この配列に追加する要素を含む別の配列。

解説

このプロセスでは、このインデックスにある既存の要素を (インデックスをインクリメントして) 上にシフトし、その上にあるすべての要素を上にシフトします。

2 番目のバージョンでは、nStartIndex位置から始まる別のCArray コレクションのすべての要素が挿入されます。

これに対し、 SetAt 関数は、指定された 1 つの配列要素を置き換え、要素をシフトしません。

// 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

CArray::IsEmpty

配列が空かどうかを判断します。

BOOL IsEmpty() const;

戻り値

配列に要素が含まれている場合は 0 以外。それ以外の場合は 0。

CArray::operator []

これらの添字演算子は、 SetAt 関数と GetAt 関数の代わりに便利です。

TYPE& operator[](int_ptr nindex);
const TYPE& operator[](int_ptr nindex) const;

パラメーター

TYPE
この配列内の要素の型を指定するテンプレート パラメーター。

nIndex
アクセスする要素のインデックス。

解説

constされていない配列に対して呼び出される最初の演算子は、代入ステートメントの右 (r 値) または左 (l 値) で使用できます。 2 つ目は、 const 配列に対して呼び出され、右側でのみ使用できます。

ライブラリのデバッグ バージョンは、下付き文字 (代入ステートメントの左側または右側) が範囲外の場合にアサートします。

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;
}

CArray::RelocateElements

配列を拡大または縮小する必要があるときに、データを新しいバッファーに再配置します。

template<class TYPE, class ARG_TYPE>
AFX_INLINE void CArray<TYPE, ARG_TYPE>::RelocateElements(
    TYPE* pNewData,
    const TYPE* pData,
    INT_PTR nCount);

パラメーター

pNewData
要素の配列の新しいバッファー。

pData
要素の古い配列。

nCount
古い配列内の要素の数。

解説

pNewData は常にすべての pData 要素を保持するのに十分な大きさです。

CArray実装では、このメソッドを使用して、配列を拡大または縮小する必要があるとき (SetSizeまたはFreeExtraが呼び出されたときに) 古いデータを新しいバッファーにコピーします。 既定の実装では、データがコピーされます。

要素に独自のメンバーへのポインターが含まれている配列、または配列要素の 1 つへのポインターが別の構造体に含まれている場合、ポインターはプレーン コピーでは更新されません。 この場合、関連する型で RelocateElements の特殊化を実装することで、ポインターを修正できます。 また、データのコピーも行う必要があります。

CArray::RemoveAll

この配列からすべての要素を削除します。

void RemoveAll();

解説

配列が既に空の場合、関数は引き続き機能します。

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

CArray::RemoveAt

配列内の指定したインデックスから始まる 1 つ以上の要素を削除します。

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

パラメーター

nIndex
0 以上で、 GetUpperBoundによって返される値以下の整数インデックス。

nCount
削除する要素の数を指定します。

解説

このプロセスでは、削除された要素の上にあるすべての要素を下にシフトします。 配列の上限はデクリメントされますが、メモリは解放されません。

削除ポイントの上にある配列に含まれている要素よりも多くの要素を削除しようとすると、ライブラリのデバッグ バージョンがアサートされます。

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

CArray::SetAt

指定したインデックス位置に配列要素を設定します。

void SetAt(INT_PTR nIndex, ARG_TYPE newElement);

パラメーター

nIndex
0 以上で、 GetUpperBoundによって返される値以下の整数インデックス。

ARG_TYPE
配列要素の参照に使用される引数の型を指定するテンプレート パラメーター。

newElement
指定した位置に格納される新しい要素の値。

解説

SetAt では、配列が拡大することはありません。 配列を自動的に拡大する場合は、 SetAtGrow を使用します。

インデックス値が配列内の有効な位置を表していることを確認する必要があります。 範囲外の場合は、ライブラリのデバッグ バージョンがアサートされます。

GetAt の例を参照してください。

CArray::SetAtGrow

指定したインデックス位置に配列要素を設定します。

void SetAtGrow(INT_PTR nIndex, ARG_TYPE newElement);

パラメーター

nIndex
0 以上の整数インデックス。

ARG_TYPE
配列内の要素の型を指定するテンプレート パラメーター。

newElement
この配列に追加する要素。 NULL値を使用できます。

解説

必要に応じて配列が自動的に拡張されます (つまり、新しい要素に合わせて上限が調整されます)。

// 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

CArray::SetSize

空または既存の配列のサイズを確立します。は、必要に応じてメモリを割り当てます。

void SetSize(
    INT_PTR nNewSize,
    INT_PTR nGrowBy = -1);

パラメーター

nNewSize
新しい配列サイズ (要素の数)。 0 以上である必要があります。

nGrowBy
サイズの増加が必要な場合に割り当てる要素スロットの最小数。

解説

新しいサイズが古いサイズより小さい場合、配列は切り捨てられ、未使用のすべてのメモリが解放されます。

配列の使用を開始する前に、この関数を使用して配列のサイズを設定します。 SetSize を使用しない場合、配列に要素を追加すると、配列の再割り当てとコピーが頻繁に発生します。 頻繁な再割り当てとコピーは非効率であり、メモリが断片化される可能性があります。

nGrowBy パラメーターは、配列の拡大中に内部メモリの割り当てに影響します。 その使用は、 GetSize および GetUpperBoundによって報告される配列サイズには影響しません。 既定値が使用されている場合、MFC はメモリの断片化を回避し、ほとんどの場合の効率を最適化するために計算された方法でメモリを割り当てます。

GetData の例を参照してください。

関連項目

MFC サンプル COLLECT
CObject クラス
階層図
CObArray クラス
コレクション クラスのヘルパー