次の方法で共有


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

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 クラスでは、さらに [ ] 演算子をオーバーロードします。 上記の 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 オブジェクトへのポインターを格納します。 リストの宣言は、「 配列を反復処理するには 」の配列に対する宣言に似ていますが、 CObListクラスから派生しています。 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 コレクションの全オブジェクトの削除」を参照してください。

関連項目

コレクション