コレクションの全メンバーへのアクセス

MFC 配列コレクション クラスは、 — テンプレートベースのクラスであり、インデックスを使用して — 要素にアクセスすることはできません。 MFC リストクラスとマップ コレクション クラスは、テンプレートベースのクラスであり、POSITION 型のインジケーターを使用してコレクション内の特定の位置 —— を記述することはできません。 — そのコレクションの 1 つ以上のメンバーにアクセスするには、まず、ポジション インジケーターを初期化し、次にそのポジションを繰り返しコレクションに渡して、次の要素の位置を問い合わせます。 コレクションは、反復の進行に関する状態情報を保持していません。 この情報は、ポジション インジケーターで保持されます。 ただし、特定のポジションについては、コレクションはそのポジションの次の要素を返します。

次に、MFC が提供する代表的な 3 種類のコレクションに対する反復処理について説明します。

配列を反復処理するには

  1. 連続したインデックス番号を使用して、 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 オブジェクトへのポインターを格納する型付きポインター配列を使っています。 この配列は、定義済みの非テンプレート クラスである CObArrayクラスから派生しています。 GetAtCPerson オブジェクトへのポインターを返します。 型指定されたポインター コレクション クラスの配列またはリストの場合、最初のパラメーターは基本クラスを指定します。2 番目のパラメーターは格納 —— する型を指定します。

    また、 クラスは [ ] 演算子をオーバーロードして、通常の配列添字構文を使用して配列の CTypedPtrArray 要素にアクセスできます。 CTypedPtrArray 上記の for ループ本体のステートメントは、次のように書き換えることができます。

    CPerson *thePerson = myArray[i];
    

    この演算子は、 と 以外 const のバージョンの両方 const に存在します。 配列 const に対して呼び出されるバージョン const は、代入ステートメントの右側にのみ表示できます。

リストを反復処理するには

  1. リスト内の項目を順に処理するには、 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 オブジェクトへのポインターを格納します。 リストの宣言は、「 配列を反復処理するには 」の配列に対する宣言に似ていますが、 クラスから派生しています。 GetNextCPerson オブジェクトへのポインターを返します。

マップを反復処理するには

  1. 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へのポインターにキャストする必要があります。

    Note

    非テンプレート マップの場合、コンパイラには、 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 コレクションの全オブジェクトの削除」を参照してください。

関連項目

コレクション