次の方法で共有


CFixedStringT : カスタム文字列マネージャーの例

ATL ライブラリは、CFixedStringT クラスで使用される CFixedStringMgr というカスタム文字列マネージャーの例を実装します。 CFixedStringTCStringT から派生し、CFixedStringTt_nChars テンプレート パラメーターで指定された長さより文字列が短い場合に、文字データを CFixedStringT オブジェクト自体の一部として割り当てる文字列を実装します。 この方法では、文字列の長さが固定バッファーのサイズを超えない限り、文字列はヒープをまったく必要としません。 CFixedStringT は文字列データの割り当てに常にヒープを使用するわけではないため、文字列マネージャーとして CAtlStringMgr を使用できません。 カスタム文字列マネージャー (CFixedStringMgr) を使用し、IAtlStringMgr インターフェイスを実装します。 このインターフェイスについては、「カスタム文字列マネージャーの実装 (高度な方法)」で説明します。

CFixedStringMgr のコンストラクターは、3 つのパラメーターを使用します。

  • pData: 使用する固定の CStringData 構造体へのポインター

  • nChars: CStringData 構造体が保持できる最大文字数

  • **pMgr: **"バックアップ文字列マネージャー" の IAtlStringMgr インターフェイスへのポインター

コンストラクターは、pDatapMgr の値をそれぞれのメンバー変数 (m_pDatam_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 の実装は、固定バッファーを返します。 CFixedStringMgrCStringT は一対一対応であるため、CStringT の特定のインスタンスが一度に複数のバッファーを使用することはありません。 したがって、nil 文字列と実際の文字列バッファーが同時に必要になることはありません。

固定バッファーが使用されていないときは、CFixedStringMgr はバッファーが長さ 0 で初期化されていることを保証します。 これにより、固定バッファーを nil 文字列として使用できます。 さらに、固定バッファーの nAllocLength メンバーは、常に固定バッファーのサイズ全体に設定されます。 したがって、CStringT は、nil 文字列の場合でも、IAtlStringMgr::Reallocate を呼び出さずに文字列を拡張できます。

要件

**ヘッダー:**cstringt.h

参照

概念

CStringT によるメモリ管理