Implementación de un administrador de cadenas personalizado (método avanzado)
En situaciones especializadas, es posible que quiera implementar un administrador de cadenas personalizado que haga algo más que cambiar el montón que se usa para asignar memoria. En esta situación, debe implementar manualmente la interfaz IAtlStringMgr como administrador de cadenas personalizado.
Para ello, es importante comprender primero cómo CStringT usa esa interfaz para administrar sus datos de cadena. Cada instancia de CStringT
tiene un puntero a una estructura CStringData. Esta estructura de longitud variable contiene información importante sobre la cadena (por ejemplo, longitud), así como los datos de caracteres reales de la cadena. Cada administrador de cadenas personalizado es responsable de asignar y liberar estas estructuras a petición de CStringT
.
La estructura CStringData
consta de cuatro campos:
pStringMgr Este campo apunta a la interfaz
IAtlStringMgr
que se usa para administrar estos datos de cadena. CuandoCStringT
necesita reasignar o liberar el búfer de cadenas, llama a los métodos Reallocate o Free de esta interfaz, pasando la estructuraCStringData
como parámetro. Al asignar una estructuraCStringData
en el administrador de cadenas, debe establecer este campo para que apunte al administrador de cadenas personalizado.nDataLength Este campo contiene la longitud lógica actual de la cadena almacenada en el búfer, excepto el valor null de terminación.
CStringT
actualiza este campo cuando la longitud de la cadena cambia. Al asignar una estructuraCStringData
, el administrador de cadenas debe establecer este campo en cero. Al reasignar una estructuraCStringData
, el administrador de cadenas personalizado debe dejar este campo sin cambios.nAllocLength Este campo contiene el número máximo de caracteres (excepto el valor null de terminación) que se puede almacenar en este búfer de cadena sin reasignarlo. Siempre que
CStringT
necesite aumentar la longitud lógica de la cadena, primero comprueba este campo para asegurarse de que hay suficiente espacio en el búfer. Si se produce un error en la comprobación,CStringT
llama al administrador de cadenas personalizado para reasignar el búfer. Al asignar o reasignar una estructuraCStringData
, debe establecer este campo en al menos el número de caracteres solicitados en el parámetro nChars en IAtlStringMgr::Allocate o IAtlStringMgr::Reallocate. Si hay más espacio del solicitado en el búfer, puede establecer este valor para reflejar la cantidad real de espacio disponible. Esto permite aCStringT
aumentar la cadena para rellenar todo el espacio asignado antes de que tenga que volver a llamar al administrador de cadenas para reasignar el búfer.nRefs Este campo contiene el recuento de referencias actual del búfer de cadenas. Si el valor es uno, una única instancia de
CStringT
usa el búfer. Además, la instancia puede leer y modificar el contenido del búfer. Si el valor es mayor que uno, varias instancias deCStringT
pueden usar el búfer. Dado que el búfer de caracteres se comparte, las instanciasCStringT
solo pueden leer el contenido del búfer. Para modificar el contenido,CStringT
hace primero una copia del búfer. Si el valor es negativo, solo una instancia deCStringT
usa el búfer. En este caso, el búfer se considera bloqueado. Cuando una instanciaCStringT
usa un búfer bloqueado, ninguna otra instancia deCStringT
puede compartir el búfer. En su lugar, estas instancias crean una copia del búfer antes de manipular el contenido. Además, la instanciaCStringT
que usa el búfer bloqueado no intenta compartir el búfer de ninguna otra instanciaCStringT
asignada. En este caso, la instanciaCStringT
copia la otra cadena en el búfer bloqueado.Al asignar una estructura
CStringData
, debe establecer este campo para reflejar el tipo de uso compartido permitido para el búfer. Para la mayoría de las implementaciones, establezca este valor en uno. Esto permite el comportamiento habitual de uso compartido de copia en escritura. Pero si el administrador de cadenas no admite el uso compartido del búfer de cadenas, establezca este campo en un estado bloqueado. Esto obliga aCStringT
a usar solo este búfer para la instancia deCStringT
que lo asignó.