方法 : タイプ セーフなコレクションを作成する
この技術情報では、タイプセーフなコレクションにデータ型を独自にする方法について説明します。ここでは、次の内容について説明します。
タイプ セーフのテンプレート ベースのクラスを使用する
ヘルパー関数の実行
非テンプレート クラスを使用してコレクション
Microsoft Foundation Class ライブラリには、 C++ テンプレートに基づいて定義済みタイプセーフなコレクションを提供します。これらのテンプレートであるため、これらのクラスは非テンプレート クラスをこのように使用する場合には型キャストないタイプ セーフと使い方などの追加の作業が確保できます。MFC のサンプル Collect アプリケーションは、 MFC のテンプレート ベースのコレクション クラスの使用方法を示します。一般に、新しいコレクション コードを記述、これらのクラスを使用します。
タイプ セーフのテンプレート ベースのクラスを使用する
テンプレート ベースのクラスを使用するには
コレクション クラス型の変数を宣言します。次に例を示します。
CList<int, int> m_intList;
コレクション オブジェクトのメンバー関数を呼び出します。次に例を示します。
m_intList.AddTail(100); m_intList.RemoveAll();
必要に応じて、 ヘルパー関数 と SerializeElementsを実行します。これらの関数の実行の詳細については、 ヘルパー関数の実行を参照してください。
この例では、整数のリストの宣言を示しています。手順 1 の最初のパラメーターは、リストの要素として格納されるデータの型です。2 番目のパラメーターは、データをどのように渡され、 追加 と GetAtなどのコレクション クラスのメンバー関数から返す必要があるかを指定します。
ヘルパー関数の実行
コレクション、派生クラスのために必要に応じてカスタマイズできるテンプレート ベースのコレクション クラス CArray、 CListおよびの使用 CMap 5 のグローバルなヘルパー関数。これらのヘルパー関数の詳細については、 *" MFC リファレンス "*の コレクション クラスのヘルパー を参照してください。シリアル化の関数の実装は、テンプレート ベースのコレクション クラスのほとんどの使用に必要です。
要素のシリアル化
CArray、 CListと CMap のクラスは、コレクション要素をに保存するか、アーカイブから読み取るに SerializeElements をダイヤルします。
SerializeElements のヘルパー関数の既定の実装は、オブジェクトが格納されるか、アーカイブから取得されているかどうかをオブジェクトからのビットごとのアーカイブからオブジェクトに、によって読み取られるアーカイブに作成した、またはビットごとにします。この操作が適切でない場合 SerializeElements をオーバーライドします。
CObject と、から派生したコレクションのストアのオブジェクトがコレクション要素クラスの実装で IMPLEMENT_SERIAL マクロを使用すると、 CArchive と CObjectに組み込まれているシリアル化の機能を利用する場合:
CArray< CPerson, CPerson& > personArray;
template <> void AFXAPI SerializeElements <CPerson> (CArchive& ar,
CPerson* pNewPersons, INT_PTR nCount)
{
for (int i = 0; i < nCount; i++, pNewPersons++)
{
// Serialize each CPerson object
pNewPersons->Serialize(ar);
}
}
CArchive のオーバーロードされた出力ストリーム演算子は CObject::Serialize (または CPerson の各オブジェクトのその関数のオーバーライドをダイヤル)します。
非テンプレート クラスを使用してコレクション
MFC は、 MFC Version 1.0 で導入されたコレクション クラスをサポートします。これらのクラスはテンプレートに基づいていません。これらがサポートされている型 CObject*、 uint、 DWORDと CStringのデータを格納するために使用できます。( CObListなど) CObjectから派生した任意のオブジェクトのコレクションを保留には、これらの定義済みコレクションを使用できます。MFC は、 uint と void ポインター (void保留にそのほかの定義済みコレクションを *)などのプリミティブ型を提供します。ただし、通常は頻繁に定義すると便利より具体的なクラスとその派生クラスのオブジェクトを保留にタイプセーフなコレクションを作成することです。テンプレートに基づいてコレクション クラスとそれがテンプレート ベースのクラスを使用するより多くの作業であることに注意してください。
非テンプレートのコレクションとタイプセーフなコレクションを作成する方法が 2 つあります:
型キャストがある非テンプレートのコレクションを、必要に応じて使用します。これはより簡単な方法です。
から派生し、非テンプレート タイプセーフなコレクションを拡張します。
型キャストがある非テンプレートのコレクションを使用するには
非テンプレート クラスの 1 つがを、 CWordArrayなど、直接使用します。
たとえば、 CWordArray を作成し、 32 ビット値を追加し、それらを取得します。もうすることは何もありません。で、定義された機能を使用します。
オブジェクトを CObjectから派生した保留には、定義済みのコレクションを、 CObListのように使用できます。CObList の収集が CObjectにポインターを保留に定義されます。一覧からオブジェクトを取得する場合、 CObList の関数が CObjectへのポインターを返すため、適切な結果を型にキャストする必要があります。たとえば、 CObList のコレクションに CPerson のオブジェクトを格納する場合は、 CPerson のオブジェクトへのポインターである場合、取得した要素をキャストする必要があります。次の例は CPerson のオブジェクトを保留に CObList のコレクションを使用します:
CPerson* p1 = new CPerson(); CObList myList; myList.AddHead(p1); // No cast needed CPerson* p2 = (CPerson*)myList.GetHead();
定義済みコレクション型を使用すると整数としてキャストこの手法は収集のための多数のために十分な場合があります。そのほかの機能の詳細にタイプ セーフが必要な場合は、テンプレート ベースのクラスを使用するか、次の手順に従います。
非テンプレート タイプセーフなコレクションを拡張するには、取得
独自の定義済みの非テンプレート クラスの 1 種類のコレクション クラスを派生します。
クラスを派生すると、既存の関数に対してタイプ セーフなインターフェイスを提供するタイプ セーフなラッパー関数を追加できます。
たとえば、 CPerson のオブジェクトを保留に CObList からボックスが表示されたら、次に示すように、ラッパー関数 AddHeadPerson と GetHeadPersonを追加する場合があります。
class CPersonList : public CObList { public: void AddHeadPerson( CPerson* person ) {AddHead( person );} const CPerson* GetHeadPerson() {return (CPerson*)GetHead();} };
これらのラッパー関数は、から派生した一覧から CPerson のオブジェクトを追加および取得するタイプセーフな方法を提供します。GetHeadPerson の関数に対して、型キャストをカプセル化していることを確認できます。
また、拡張する新しい関数を定義することで、新しい機能を追加し、タイプ セーフなラッパーの既存の機能をラップするのではなく、コレクションの機能が。たとえば、技術情報 CObject のコレクションのすべてのオブジェクトの削除 はリストのすべてに含まれるオブジェクトを削除するための関数について説明します。この関数は、メンバー関数として派生クラスに追加できます。