次の方法で共有


カスタム文字列マネージャーの実装 (高度なメソッド)

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

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

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

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

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

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

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

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

関連項目

CStringT によるメモリ管理