次の方法で共有


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

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

CFixedStringMgr のコンストラクターは 3 つのパラメーターを受け取ります。

  • pData: 使う固定 CStringData 構造体へのポインター。

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

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

コンストラクターは pDatapMgr の値をそれぞれのメンバー変数 (m_pDatam_pMgr) に格納します。 次に、バッファーの長さを 0 に、使用できる長さを固定バッファーの最大サイズに、参照カウントを - 1 に設定します。 参照カウント値は、バッファーがロックされ、この CFixedStringMgr のインスタンスを文字列マネージャーとして使うことを示します。

バッファーをロックされたものとマークすることで、他の CStringT インスタンスがバッファーへの共有参照を保持できなくなります。 他の CStringT インスタンスがバッファーを共有することを許可された場合、他の文字列がまだバッファーを使っている間に、CFixedStringT によって格納されたバッファーが削除される可能性があります。

CFixedStringMgrIAtlStringMgr インターフェイスの完全な実装です。 各メソッドの実装については、個別に説明します。

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 の実装により、固定バッファーが返されます。 CFixedStringMgrCStringT は 1 対 1 で対応しているため、CStringT の特定のインスタンスが一度に複数のバッファーを使うことはありません。 そのため、nil 文字列と実文字列のバッファーが同時に必要になることはありません。

固定バッファーが使われていないときは常に、CFixedStringMgr によって確実に 0 の長さで初期化されます。 これにより、nil 文字列として使うできます。 さらに、固定バッファーの nAllocLength メンバーは、常に固定バッファーのフル サイズに設定されるというボーナスもあります。 つまり、nil 文字列であっても、IAtlStringMgr::Reallocate を呼び出すことなく、CStringT を使って文字列を拡張することができます。

要件

ヘッダー: cstringt.h

関連項目

CStringT によるメモリ管理