次の方法で共有


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

更新 : 2007 年 11 月

特殊な状況では、メモリの割り当てに使用されるヒープを変更する以外の処理を行うカスタム文字列マネージャの実装が必要な場合があります。このような状況では、カスタム文字列マネージャとして 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 によるメモリ管理