Partilhar via


Implementação de um gerenciador de cadeia de caracteres personalizada (método avançado)

Em situações especializadas, talvez você queira implementar um gerenciador de cadeia de caracteres personalizado que faça mais do que apenas alterar qual heap é usado para alocar memória. Nessa situação, você deve implementar manualmente a interface IAtlStringMgr como seu gerenciador de cadeia de caracteres personalizado.

Para fazer isso, é importante primeiro entender como o CStringT usa essa interface para gerenciar seus dados de cadeia de caracteres. Cada instância tem CStringT um ponteiro para uma estrutura CStringData. Essa estrutura de comprimento variável contém informações importantes sobre a cadeia de caracteres (como comprimento), bem como os dados de caractere reais da cadeia de caracteres. Cada gerenciador de cadeia de caracteres personalizado é responsável por alocar e liberar essas estruturas a pedido de CStringT.

A estrutura CStringData é composta por quatro campos:

  • pStringMgr Esse campo aponta para a interface IAtlStringMgr usada para gerenciar esses dados de cadeia de caracteres. Quando CStringT precisar realocar ou liberar o buffer de cadeia de caracteres, ele chamará os métodos Reallocate ou Free dessa interface, passando a estrutura CStringData como um parâmetro. Ao alocar uma estrutura CStringData no gerenciador de cadeia de caracteres, você deverá definir esse campo para apontar para o gerenciador de cadeia de caracteres personalizado.

  • nDataLength Esse campo contém o comprimento lógico atual da cadeia de caracteres armazenada no buffer, excluindo o nulo de encerramento. CStringT atualiza esse campo quando o comprimento da cadeia de caracteres é alterado. Ao alocar uma estrutura CStringData, o gerenciador de cadeia de caracteres deverá definir esse campo como zero. Ao realocar uma estrutura CStringData, o gerenciador de cadeia de caracteres personalizado deverá deixar esse campo inalterado.

  • nAllocLength Esse campo contém o número máximo de caracteres (excluindo o nulo de encerramento) que podem ser armazenados neste buffer de cadeia de caracteres sem realocá-lo. Sempre que CStringT precisar aumentar o comprimento lógico da cadeia de caracteres, ele primeiro verificará esse campo para verificar se há espaço suficiente no buffer. Se a verificação falhar, CStringT chamará o gerenciador de cadeia de caracteres personalizado para realocar o buffer. Ao alocar ou realocar uma estrutura CStringData, você deve definir esse campo como pelo menos o número de caracteres solicitados no parâmetro nChars para IAtlStringMgr::Allocate ou IAtlStringMgr::Reallocate. Se houver mais espaço no buffer do que o solicitado, você poderá definir esse valor para refletir a quantidade real de espaço disponível. Isso permite que CStringT aumente a cadeia de caracteres para preencher todo o espaço alocado antes de precisar chamar de volta para o gerenciador de cadeias de caracteres para realocar o buffer.

  • nRefs Esse campo contém a contagem de referência atual do buffer de cadeia de caracteres. Se o valor for um, uma única instância de CStringT estará usando o buffer. Além disso, a instância tem permissão para ler e modificar o conteúdo do buffer. Se o valor for maior que um, várias instâncias de CStringT poderão usar o buffer. Como o buffer de caracteres é compartilhado, as instâncias CStringT só podem ler o conteúdo do buffer. Para modificar o conteúdo, CStringT primeiro faz uma cópia do buffer. Se o valor for negativo, apenas uma instância de CStringT estará usando o buffer. Nesse caso, o buffer é considerado bloqueado. Quando uma instância CStringT estiver usando um buffer bloqueado, nenhuma outra instância de CStringT poderá compartilhar o buffer. Em vez disso, essas instâncias criam uma cópia do buffer antes de manipular o conteúdo. Além disso, a instância CStringT que usa o buffer bloqueado não tenta compartilhar o buffer de qualquer outra instância CStringT atribuída a ele. Nesse caso, a instância CStringT copia a outra cadeia de caracteres no buffer bloqueado.

    Ao alocar uma estrutura CStringData, você deverá definir esse campo para refletir o tipo de compartilhamento permitido para o buffer. Para a maioria das implementações, defina esse valor como um. Isso permite o comportamento usual de compartilhamento de cópia na gravação. No entanto, se o gerenciador de cadeias de caracteres não der suporte ao compartilhamento do buffer de cadeia de caracteres, defina esse campo como um estado bloqueado. Isso força CStringT a usar somente esse buffer para a instância do CStringT que o alocou.

Confira também

Gerenciamento de memória com CStringT