MFC 配列コレクション クラスは、テンプレート ベースと非両方のクラスで、インデックスを使用して要素にアクセスします。 MFC リストおよびマップ コレクション クラスは、テンプレート ベースとマップ コレクション クラスの両方で、 POSITION 型のインジケーターを使用して、コレクション内の特定の位置を記述します。 これらのコレクションの 1 つ以上のメンバーにアクセスするには、まず位置インジケーターを初期化してから、その位置をコレクションに繰り返し渡し、次の要素を返すように要求します。 コレクションは、イテレーションの進行状況に関する状態情報を維持する責任を負いません。 その情報は位置インジケーターに保持されます。 ただし、特定の位置を指定すると、コレクションは次の要素を返す役割を担います。
次の手順では、MFC で提供される 3 種類のコレクションを反復処理する方法を示します。
配列を反復処理するには
GetAt
メンバー関数で順次インデックス番号を使用します。CTypedPtrArray<CObArray, CPerson *> myArray; myArray.Add(new CPerson()); for (int i = 0; i < myArray.GetSize(); i++) { CPerson *thePerson = myArray.GetAt(i); thePerson->AssertValid(); }
この例では、
CPerson
オブジェクトへのポインターを含む型指定されたポインター配列を使用します。 配列は、非テンプレートの定義済みクラスの 1 つであるクラスCObArray
から派生します。GetAt
は、CPerson
オブジェクトへのポインターを返します。 型指定されたポインター コレクション クラス (配列またはリスト) の場合、最初のパラメーターは基底クラスを指定します。2 番目のパラメーターは、格納する型を指定します。また、
CTypedPtrArray
クラスは [] 演算子をオーバーロードして、配列の要素にアクセスするためのカスタム配列添字構文を使用できるようにします。 上記のfor
ループ本体のステートメントは、次のように書き換えることができます。CPerson *thePerson = myArray[i];
この演算子は、
const
バージョンとconst
以外のバージョンの両方に存在します。const
配列に対して呼び出されるconst
バージョンは、代入ステートメントの右側にのみ表示できます。
リストを反復処理するには
GetHeadPosition
メンバー関数とGetNext
を使用して、リストを操作します。CTypedPtrList<CObList, CPerson *> myList; myList.AddHead(new CPerson()); POSITION pos = myList.GetHeadPosition(); while (pos != NULL) { CPerson *thePerson = myList.GetNext(pos); thePerson->AssertValid(); }
この例では、型指定されたポインター リストを使用して、
CPerson
オブジェクトへのポインターを格納します。 リスト宣言は、配列を 反復処理する プロシージャの配列の宣言に似ていますが、クラスCObList
から派生します。GetNext
は、CPerson
オブジェクトへのポインターを返します。
マップを反復処理するには
次の例に示すように、
GetStartPosition
を使用してマップの先頭に移動し、GetNextAssoc
を使用してマップから次のキーと値を繰り返し取得します。CMap<CString, LPCTSTR, CPerson *, CPerson *> myMap; CPerson myPerson; myMap.SetAt(_T("Bill"), &myPerson); POSITION pos = myMap.GetStartPosition(); while (pos != NULL) { CPerson *pPerson; CString string; // Get key (string) and value (pPerson) myMap.GetNextAssoc(pos, string, pPerson); // Use string and pPerson }
この例では、
CString
キーを使用し、CPerson
オブジェクトへのポインターを格納する単純なマップ テンプレート (型指定されたポインター コレクションではなく) を使用します。GetNextAssoc
などのアクセス関数を使用する場合、クラスはCPerson
オブジェクトへのポインターを提供します。 代わりに非テンプレート マップ コレクションのいずれかを使用する場合は、返されたCObject
ポインターをCPerson
へのポインターにキャストする必要があります。注
非テンプレート マップの場合、コンパイラは
CObject
の最後のパラメーターにおいてGetNextAssoc
ポインターへの参照が必要です。 次の例に示すように、入力時にポインターをその型にキャストする必要があります。テンプレート ソリューションはシンプルで、タイプ セーフの向上に役立ちます。 次に示すように、非テンプレート コードはより複雑です。
CMapStringToOb myMap; // A nontemplate collection class CPerson myPerson; myMap.SetAt(_T("Bill"), &myPerson); POSITION pos = myMap.GetStartPosition(); while (pos != NULL) { CPerson *pPerson; CString string; // Gets key (string) and value (pPerson) myMap.GetNextAssoc(pos, string, (CObject *&)pPerson); ASSERT(pPerson->IsKindOf(RUNTIME_CLASS(CPerson))); // Use string and pPerson ... }
詳細については、「 CObject コレクション内のすべてのオブジェクトの削除」を参照してください。