CFixedStringT: カスタム文字列マネージャーの例
ATL ライブラリには、クラス CFixedStringT で使うカスタム文字列マネージャーの一例 (CFixedStringMgr と呼ばれます) が実装されています。 CFixedStringT
は CStringT から派生したものです。文字列が CFixedStringT
の t_nChars
テンプレート パラメーターで指定された長さ未満の場合、CFixedStringT
オブジェクトの一部としてその文字データを割り当てる文字列を実装しています。 この方法では、文字列の長さが固定バッファーのサイズを超えない限り、文字列にヒープはまったく必要ありません。 CFixedStringT
からは、文字列データの割り当てに常にヒープを使うわけではないので、CAtlStringMgr
を文字列マネージャーとして使うことはできません。 IAtlStringMgr インターフェイスを実装して、カスタム文字列マネージャー (CFixedStringMgr
) を使います。 このインターフェイスについては、「カスタム文字列マネージャー (高度なメソッド) の実装」を参照してください。
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
の 1 つのインスタンスにのみ関連付けることができるために起こります。 CStringT
の他のインスタンスがマネージャーをクローンする場合、代わりにバックアップ マネージャーを取得する必要があります。 これは、バックアップ マネージャーが共有をサポートしているからです。
CFixedStringMgr::GetNilString の実装
CFixedStringMgr::GetNilString
の実装により、固定バッファーが返されます。 CFixedStringMgr
と CStringT
は 1 対 1 で対応しているため、CStringT
の特定のインスタンスが一度に複数のバッファーを使うことはありません。 そのため、nil 文字列と実文字列のバッファーが同時に必要になることはありません。
固定バッファーが使われていないときは常に、CFixedStringMgr
によって確実に 0 の長さで初期化されます。 これにより、nil 文字列として使うできます。 さらに、固定バッファーの nAllocLength
メンバーは、常に固定バッファーのフル サイズに設定されるというボーナスもあります。 つまり、nil 文字列であっても、IAtlStringMgr::Reallocate を呼び出すことなく、CStringT
を使って文字列を拡張することができます。
要件
ヘッダー: cstringt.h