テンプレート ベースのクラス
このアーティクルでは、MFC バージョン3.0 以降のタイプ セーフなテンプレートベースのコレクション クラスについて説明します。 これらのテンプレートを使ってタイプ セーフなコレクションを作成することは、テンプレートに基づかないコレクション クラスを使うよりも便利で、より効果的にタイプ セーフを提供できます。
MFC 事前定義には、テンプレート ベースのコレクションの 2 つのカテゴリがあります:
単純なコレクション クラスはすべてクラス CObject
から派生するので、CObject
のシリアル化、動的な作成、およびその他のプロパティを継承します。 型指定されたポインター コレクション クラスでは、派生元のクラスを指定する必要があります。これは、CPtrList
や CPtrArray
など、MFC によって定義済みの非テンプレート ポインター コレクションのいずれかでなければなりません。 新しいコレクション クラスは、指定された基底クラスを継承し、新しいクラスのメンバー関数は、基底クラスのメンバーへのカプセル化された呼び出しを使用して、タイプ セーフを適用します。
C++ テンプレートの詳細は、C++ 言語リファレンスのテンプレートを参照してください。
単純な配列、リスト、マップ テンプレートの使用
単純なコレクション テンプレートを使用するには、これらのコレクションに格納できるデータの種類と、コレクション宣言で使用するパラメーターを把握しておく必要があります。
単純な配列とリストの使用法
単純な配列クラスとリスト クラス CArray と CList では、TYPE と ARG_TYPE
の 2 つのパラメーターを受け取ります。 これらのクラスは、TYPE パラメーターで指定する任意のデータ型を格納できます。
int
、char
、float
などの基本的な C++ データ型C++ 構造体とクラス
定義するその他の型
利便性と効率性を高めるために、ARG_TYPE パラメーターを使用して関数の引数の型を指定できます。 通常は、TYPE パラメーターで指定した型への参照として ARG_TYPE を指定します。 次に例を示します。
CArray<int, int> myArray;
CList<CPerson, CPerson &> myList;
最初の例では、**int
**s を含む配列コレクション myArray
を宣言しています。 2番目の例では、CPerson
オブジェクトを格納するリスト コレクション myList
を宣言します。 コレクション クラスの特定のメンバー関数は、ARG_TYPE テンプレート パラメーターによって型が指定された引数を受け取ります。 たとえば、クラス CArray
の Add
メンバー関数は、ARG_TYPE の引数を受け取ります:
CArray<CPerson, CPerson &> personArr;
CPerson person;
personArr.Add(person);
単純なマップの使用法
単純なマップクラス CMap は、KEY、ARG_KEY、VALUE、ARG_VALUE の 4 つのパラメーターを受け取ります。 配列クラスやリスト クラスと同様に、マップ クラスも任意のデータ型を格納できます。 格納するデータのインデックスと順序を指定する配列やリストとは異なり、マップはキーと値を関連付けます。値に関連付けられているキーを指定することによってマップに格納されている値にアクセスします。 KEY パラメーターは、マップに格納されているデータにアクセスするために使用されるキーのデータ型を指定します。 KEY の型が構造体またはクラスの場合、通常、ARG_KEY パラメーターは、KEY で指定された型への参照です。 VALUEパラメーターは、マップに格納されている項目の型を指定します。 ARG_VALUE の型が構造体またはクラスの場合、通常、ARG_VALUE パラメーターは、VALUE で指定された型への参照です。 次に例を示します。
CMap<int, int, MY_STRUCT, MY_STRUCT &> myMap1;
CMap<CString, LPCTSTR, CPerson, CPerson &> myMap2;
最初の例では、値 MY_STRUCT
を格納し、int
キーによってアクセスし、アクセスされた MY_STRUCT
項目を参照渡しで返します。 2番目の例では、値 CPerson
を格納し、CString
キーによってアクセスし、アクセスされた項目への参照を返します。 この例では、名字で人を探すような簡単なアドレス帳を表しています。
KEY パラメーターが CString
型であり、KEY_TYPE パラメーターが LPCSTR
型であるため、キーは CString
型の項目としてマップに格納されますが、LPCSTR
型のポインターによって SetAt
などの関数で参照されます。 次に例を示します。
CMap<CString, LPCTSTR, CPerson, CPerson &> myMap;
CPerson person;
LPCTSTR lpstrName = _T("Jones");
myMap.SetAt(lpstrName, person);
型指定されたポインター コレクション テンプレートの使用
型指定されたコレクション テンプレートを使用するには、これらのコレクションに格納できるデータの種類と、コレクション宣言で使用するパラメーターを把握しておく必要があります。
型指定されたポインター配列とリストの使用法
型指定されたポインターの配列とリストクラス CTypedPtrArray と CTypedPtrList は、BASE_CLASS と TYPEの 2 つのパラメーターを受け取ります。 これらのクラスは、TYPE パラメーターで指定する任意のデータ型を格納できます。 これらは、ポインターを格納する非テンプレート コレクションクラスの 1 つから派生します。この基本クラスは BASE_CLASS で指定します。 配列の場合は、CObArray
または CPtrArray
を使用します。 リストの場合は、CObList
または CPtrList
を使用します。
実際には、CObList
に基づいてコレクションを宣言すると、新しいクラスがその基底クラスのメンバーを継承するだけでなく、さらに多くのタイプセーフなメンバー関数と演算子も宣言し、基底クラスのメンバーへの呼び出しをカプセル化することによってタイプの安全性を提供することができます。 これらのカプセル化は、必要なすべての型変換を管理します。 次に例を示します。
CTypedPtrArray<CObArray, CPerson *> myArray;
CTypedPtrList<CPtrList, MY_STRUCT *> myList;
最初の例では、CObArray
から派生した型指定されたポインター配列 myArray
を宣言しています。 配列は、CPerson
オブジェクト (CPerson
は CObject
から派生したクラス) へのポインターを格納し、返します。 任意 CObArray
のメンバー関数を呼び出すことができます。または、新しいタイプセーフ GetAt
関数と ElementAt
関数を呼び出すことも、タイプセーフな [ ] 演算子を使用することもできます。
2番目の例では、CPtrList
から派生した型指定されたポインターのリスト myList
を宣言しています。 リストは、MY_STRUCT
オブジェクトへのポインターを格納し、返します。 CPtrList
に基づくクラスは、CObject
から派生していないオブジェクトへのポインターを格納するために使用されます。 CTypedPtrList
には、GetHead
、GetTail
、RemoveHead
、RemoveTail
、GetNext
、GetPrev
、および GetAt
というタイプセーフなメンバー関数が多数あります。
型指定されたポインター マップの使用状況
型指定されたポインターのマップ クラス CTypedPtrMap は、BASE_CLASS、KEY、および VALUE の 3 つのパラメーターを受け取ります。 BASE_CLASS パラメーターは、新しいクラスの派生元のクラス (CMapPtrToWord
、CMapPtrToPtr
、CMapStringToPtr
、CMapWordToPtr
、CMapStringToOb
など) を指定します。 KEY は、CMap
の KEY に似ています。これは、検索に使用されるキーの種類を指定します。 VALUE は、CMap
の VALUE に似ています。これは、マップに格納されているオブジェクトの型を指定します。 次に例を示します。
CTypedPtrMap<CMapPtrToPtr, CString, MY_STRUCT*> myPtrMap;
CTypedPtrMap<CMapStringToOb, CString, CPerson*> myPersonMap;
最初の例は、CMapPtrToPtr
に 基づくマップで、MY_STRUCT
へのポインターにマップされた CString
キーを使用します。 タイプセーフ Lookup
なメンバー関数を呼び出すことによって、格納されているポインターを検索できます。 [] 演算子を使用して、格納されているポインターを検索し、見つからない場合は追加できます。 また、タイプセーフな関数 GetNextAssoc
を使用してマップを反復処理できます。 クラス CMapPtrToPtr
の他のメンバー関数を呼び出すこともできます。
2 番目の例は、CMapStringToOb
に基づくマップで、CMyObject
オブジェクトへの格納されたポインターにマップされる文字列キーを使用します。 前の段落で説明したのと同じタイプセーフメンバーを使用することも、クラス CMapStringToOb
のメンバーを呼び出すこともできます。
Note
型へのポインターまたは参照ではなく、VALUE パラメーターに class
または struct
型を指定する場合は、クラスまたは構造体にコピー コンストラクターが必要です。
詳細は、Type-Safe コレクションを作成する方法を参照してください。