この記事では、MFC バージョン 3.0 以降のタイプ セーフなテンプレート ベースのコレクション クラスについて説明します。 これらのテンプレートを使用してタイプ セーフなコレクションを作成する方が便利であり、テンプレートに基づいていないコレクション クラスを使用するよりも、型の安全性をより効果的に提供するのに役立ちます。
MFC では、テンプレート ベースのコレクションの 2 つのカテゴリが事前に定義されています。
-
CArray
、CList
、CMap
-
CTypedPtrArray
、CTypedPtrList
、CTypedPtrMap
単純なコレクション クラスはすべてクラス CObject
から派生しているため、シリアル化、動的作成、および CObject
のその他のプロパティを継承します。 型指定されたポインター コレクション クラスでは、派生元のクラスを指定する必要があります。このクラスは、MFC によって定義済みの非テンプレート ポインター コレクション ( CPtrList
や CPtrArray
など) のいずれかである必要があります。 新しいコレクション クラスは、指定した基底クラスから継承し、新しいクラスのメンバー関数は、型の安全性を強制するために、基底クラスメンバーへのカプセル化された呼び出しを使用します。
C++ テンプレートの詳細については、「C++ 言語リファレンスの テンプレート 」 を参照してください。
単純な配列、リスト、マップ テンプレートの使用
単純なコレクション テンプレートを使用するには、これらのコレクションに格納できるデータの種類と、コレクション宣言で使用するパラメーターを把握する必要があります。
単純な配列とリストの使用法
単純な配列クラスとリスト クラス である CArray クラスと CList クラスは、 TYPE と ARG_TYPE
の 2 つのパラメーターを受け取ります。 これらのクラスは、 TYPE パラメーターで指定する任意のデータ型を格納できます。
int
、char
、などの基本的な C++ データ型float
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);
Typed-Pointer コレクション テンプレートの使用
型指定ポインター コレクション テンプレートを使用するには、これらのコレクションに格納できるデータの種類と、コレクション宣言で使用するパラメーターを把握する必要があります。
配列とリストの使用法を Typed-Pointer する
型指定ポインター配列とリスト クラス 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
関数を呼び出すか、type-safe [ ] 演算子を使用できます。
2 番目の例では、CPtrList
から派生した型指定されたポインター リスト (myList
) を宣言します。 リストは、 MY_STRUCT
オブジェクトへのポインターを格納して返します。
CPtrList
に基づくクラスは、CObject
から派生していないオブジェクトへのポインターを格納するために使用されます。
CTypedPtrList
には、 GetHead
、 GetTail
、 RemoveHead
、 RemoveTail
、 GetNext
、 GetPrev
、 GetAt
など、さまざまなタイプ セーフなメンバー関数があります。
Typed-Pointer マップの使用状況
型指定ポインター マップ クラス 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
のメンバーを呼び出すことができます。
注
型へのポインターまたは参照ではなく、VALUE パラメーターにclass
型またはstruct
型を指定する場合、クラスまたは構造体にはコピー コンストラクターが必要です。
詳細については、「 Type-Safe コレクションを作成する方法」を参照してください。