CFixedStringT : カスタム文字列マネージャの例
更新 : 2007 年 11 月
ATL ライブラリは、CFixedStringT クラスで使用される CFixedStringMgr というカスタム文字列マネージャの例を実装します。CFixedStringT は CStringT から派生し、CFixedStringT の t_nChars テンプレート パラメータで指定された長さより文字列が短い場合に、文字データを CFixedStringT オブジェクト自体の一部として割り当てる文字列を実装します。この方法では、文字列の長さが固定バッファのサイズを超えない限り、文字列はヒープをまったく必要としません。CFixedStringT は文字列データの割り当てに常にヒープを使用するわけではないため、文字列マネージャとして CAtlStringMgr を使用できません。カスタム文字列マネージャ (CFixedStringMgr) を使用し、IAtlStringMgr インターフェイスを実装します。このインターフェイスについては、「カスタム文字列マネージャの実装 (高度な方法)」で説明します。
CFixedStringMgr のコンストラクタは、3 つのパラメータを使用します。
pData: 使用する固定の CStringData 構造体へのポインタ
nChars:CStringData 構造体が保持できる最大文字数
**pMgr: **"バックアップ文字列マネージャ" の IAtlStringMgr インターフェイスへのポインタ
コンストラクタは、pData と pMgr の値をそれぞれのメンバ変数 (m_pData と m_pMgr) に格納します。次に、バッファの長さを 0 に、使用できる長さを固定バッファの最大サイズと同じに設定します。また、参照カウントを –1 に設定します。参照カウント値は、バッファがロックされており、CFixedStringMgr のこのインスタンスを文字列マネージャとして使用することを示します。
バッファにロックのマークを付けることにより、CStringT のほかのインスタンスがバッファへの共有参照を保持することを防ぎます。CStringT のほかのインスタンスがバッファの共有を許可されている場合は、ほかの文字列がまだバッファを使用している間に、CFixedStringT に含まれているバッファが削除される可能性があります。
CFixedStringMgr は、IAtlStringMgr インターフェイスの完全な実装です。各メソッドの実装について個別に説明します。
CFixedStringMgr::Allocate の実装
CFixedStringMgr::Allocate の実装は、最初に、要求されている文字列サイズが m_pData メンバに格納されている固定バッファのサイズ以下かどうかを確認します。固定バッファが十分な大きさの場合、CFixedStringMgr は固定バッファを長さ 0 でロックします。文字列の長さが固定バッファのサイズを超えない限り、CStringT はバッファを再割り当てする必要はありません。
要求された文字列サイズが固定バッファより大きい場合、CFixedStringMgr は要求をバックアップ文字列マネージャに転送します。バックアップ文字列マネージャは、ヒープからバッファを割り当てると推定されます。ただし、このバッファを返す前に、CFixedStringMgr はバッファをロックし、バッファの文字列マネージャのポインタを CFixedStringMgr オブジェクトへのポインタで置換します。これにより、CStringT によるバッファの再割り当てまたは解放の試行では CFixedStringMgr が呼び出されます。
CFixedStringMgr::ReAllocate の実装
CFixedStringMgr::ReAllocate の実装は、Allocate の実装と同様です。
再割り当てされるバッファが固定バッファであり、要求されたバッファ サイズが固定バッファより小さい場合、割り当ては行われません。ただし、再割り当てされるバッファが固定バッファでない場合は、バックアップ マネージャで割り当てられたバッファである必要があります。この場合、バックアップ マネージャがバッファの再割り当てに使用されます。
再割り当てされるバッファが固定バッファで、新規バッファ サイズが大きすぎて固定バッファに入りきらない場合は、CFixedStringMgr がバックアップ マネージャを使用して新規バッファを割り当てます。固定バッファの内容は、新規バッファにコピーされます。
CFixedStringMgr::Free の実装
CFixedStringMgr::Free の実装は、Allocate および ReAllocate と同じパターンに従います。解放されるバッファが固定バッファの場合、そのバッファを長さ 0 のロックされたバッファに設定します。解放されるバッファがバックアップ マネージャで割り当てられた場合、CFixedStringMgr はバックアップ マネージャを使用してそのバッファを解放します。
CFixedStringMgr::Clone の実装
CFixedStringMgr::Clone の実装では、CFixedStringMgr ではなくバックアップ マネージャへのポインタが常に返されます。この状況は、CFixedStringMgr の各インスタンスが CStringT の単一インスタンスとしか関連付けられないために発生します。マネージャの複製を試行する CStringT のほかのインスタンスは、代わりにバックアップ マネージャを取得する必要があります。このため、バックアップ マネージャでは共有がサポートされます。
CFixedStringMgr::GetNilString の実装
CFixedStringMgr::GetNilString の実装は、固定バッファを返します。CFixedStringMgr と CStringT は一対一対応であるため、CStringT の特定のインスタンスが一度に複数のバッファを使用することはありません。したがって、nil 文字列と実際の文字列バッファが同時に必要になることはありません。
固定バッファが使用されていないときは、CFixedStringMgr はバッファが長さ 0 で初期化されていることを保証します。これにより、固定バッファを nil 文字列として使用できます。さらに、固定バッファの nAllocLength メンバは、常に固定バッファのサイズ全体に設定されます。したがって、CStringT は、nil 文字列の場合でも、IAtlStringMgr::Reallocate を呼び出さずに文字列を拡張できます。
必要条件
ヘッダー : cstringt.h