カスタム文字列マネージャーの実装 (高度なメソッド)
特殊な状況では、メモリの割り当てに使用されるヒープを変更する以上のことを行うカスタム文字列マネージャーを実装する必要がある場合があります。 このような場合は、カスタム文字列マネージャーとして 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
インスタンスのこのバッファーのみを使用することを強制されます。