次の方法で共有


カスタム文字列マネージャーの実装 (高度な方法)

特殊な状況では、メモリの割り当てに使用されるヒープを変更する以外の処理を行うカスタム文字列マネージャーの実装が必要な場合があります。 このような状況では、カスタム文字列マネージャーとして IAtlStringMgr インターフェイスを手動で実装する必要があります。

これを実装するには、最初に、CStringT がそのインターフェイスを使用して文字列データをどのように管理するかを理解することが重要です。 CStringT の各インスタンスには、CStringData 構造体へのポインターがあります。 この可変長の構造体には、文字列に関する重要情報 (長さなど) と、文字列の実際の文字データが含まれています。 すべてのカスタム文字列マネージャーは、CStringT の要求によりこれらの構造体を割り当ておよび解放します。

CStringData 構造体は、4 つのフィールドで構成されます。

  • pStringMgr   このフィールドは、この文字列データの管理に使用される IAtlStringMgr インターフェイスをポイントします。 CStringT は、文字列バッファーを再割り当てまたは解放する必要がある場合に、CStringData 構造体をパラメーターとして、このインターフェイスの Reallocate メソッドと Free メソッドを呼び出します。 文字列マネージャーで CStringData 構造体を割り当てる場合は、このフィールドに、カスタム文字列マネージャーへのポインターを設定する必要があります。

  • nDataLength   このフィールドには、バッファーに格納されている文字列の終端の null 文字を除いた現在の論理長が含まれます。 CStringT は、文字列の長さが変化したときにこのフィールドを更新します。 CStringData 構造体を割り当てる場合は、文字列マネージャーがこのフィールドを 0 に設定する必要があります。 CStringData 構造体を再割り当てする場合、カスタム文字列マネージャーはこのフィールドを変更しないままにする必要があります。

  • nAllocLength   このフィールドには、再割り当てせずにこの文字列バッファーに格納できる最大文字数 (終端の null を除く) が含まれます。 CStringT は、文字列の論理長を増やす必要がある場合に、まずこのフィールドをチェックして、バッファーに十分な領域があることを確認します。 チェックに失敗した場合、CStringT はカスタム文字列マネージャーを呼び出してバッファーを再割り当てします。 CStringData 構造体の割り当てまたは再割り当てを行う場合は、このフィールドに、IAtlStringMgr::Allocate または IAtlStringMgr::Reallocate への nChars パラメーターで要求されている文字数以上を設定する必要があります。 要求されている領域よりも大きい領域がバッファーにある場合は、この値を設定して、使用できる実際の容量を反映できます。 これにより、CStringT は文字列を拡張し、割り当てられている容量全体が限界になってからも、文字列マネージャーを呼び出してバッファーを再割り当てできます。

  • nRefs   このフィールドには、文字列バッファーの現在の参照カウントが含まれます。 値が 1 の場合、CStringT の単一インスタンスがバッファーを使用しています。 また、インスタンスは、バッファーの内容の読み込みと変更の両方を許可されています。 値が 1 より大きい場合は、CStringT の複数のインスタンスがバッファーを使用できます。 文字バッファーは共有されるため、CStringT のインスタンスはバッファー内容の読み込みだけを行うことができます。 内容を変更するために、CStringT は最初にバッファーのコピーを作成します。 値が負の場合は、CStringT の 1 つのインスタンスだけがバッファーを使用しています。 この場合、バッファーはロックされていると見なされます。 CStringT の 1 つのインスタンスがロックされたバッファーを使用している場合、CStringT のほかのインスタンスはバッファーを共有できません。 代わりに、これらのインスタンスは、内容を操作する前にバッファーのコピーを作成します。 また、ロックされたバッファーを使用している CStringT のインスタンスは、割り当てられているほかの CStringT のインスタンスのバッファーの共有を試行しません。 この場合、CStringT のインスタンスは、ほかの文字列をロックされているバッファーにコピーします。

    CStringData 構造体を割り当てるときは、バッファーに対して許可されている共有の種類を反映するようにこのフィールドを設定する必要があります。 ほとんどの実装では、この値は 1 に設定します。 この設定では、通常の書き込み時コピー共有動作が可能になります。 ただし、文字列マネージャーが文字列バッファーの共有をサポートしていない場合は、このフィールドをロック状態に設定します。 これにより、CStringT は、このバッファーを割り当てた CStringT インスタンスに対してだけこのバッファーを使用するようになります。

参照

概念

CStringT によるメモリ管理