Compartilhar via


CFixedStringT: exemplo de um gerente de cadeia de caracteres personalizada

A biblioteca da ATL implementa um exemplo de um gerente de cadeias de caracteres personalizada usado pela classe CFixedStringT, chamado CFixedStringMgr. CFixedStringT é derivado de CStringT e implementa uma cadeia de caracteres que aloca seus dados de caractere como parte do próprio objeto CFixedStringT, desde que a cadeia de caracteres seja menor que o comprimento especificado pelo parâmetro de modelo t_nChars de CFixedStringT. Com essa abordagem, a cadeia de caracteres não precisa do heap, a menos que o comprimento da cadeia de caracteres cresça além do tamanho do buffer fixo. Como CFixedStringT nem sempre usa um heap para alocar seus dados de cadeia de caracteres, ele não pode usar CAtlStringMgr como um gerente de cadeira de caracteres. Ele usa um gerente de cadeia de caracteres personalizado (CFixedStringMgr), implementando a interface IAtlStringMgr. Essa interface é discutida em Implementação de um gerente de cadeia de caracteres personalizado (método Avançado).

O construtor para CFixedStringMgr usa três parâmetros:

  • pData: um ponteiro para a estrutura fixa CStringData a ser usada.

  • nChars: o número máximo de caracteres que a estrutura CStringData pode conter.

  • pMgr: um ponteiro para a interface IAtlStringMgr de um "gerente de cadeias de caracteres de backup".

O construtor armazena os valores de pData e pMgr em suas respectivas variáveis de membro (m_pData e m_pMgr). Em seguida, ele define o comprimento do buffer como zero, o comprimento disponível igual ao tamanho máximo do buffer fixo e a contagem de referência como -1. O valor da contagem de referência indica que o buffer está bloqueado e para usar essa instância de CFixedStringMgr como o gerente de cadeia de caracteres.

Marcar o buffer como bloqueado impede que outras instâncias de CStringT retenham uma referência compartilhada ao buffer. Se outras instâncias de CStringT tivessem permissão para compartilhar o buffer, seria possível excluir o buffer contido por CFixedStringT de ser excluído enquanto outras cadeias de caracteres ainda estavam usando o buffer.

CFixedStringMgr é uma implementação da interface IAtlStringMgr. A implementação de cada método é discutida separadamente.

Implementação de CFixedStringMgr::Allocate

A implementação de CFixedStringMgr::Allocate primeiro verifica para ver se o tamanho solicitado da cadeia de caracteres é menor ou igual ao tamanho do buffer fixo (armazenado no membro m_pData). Se o buffer fixo for grande o suficiente, CFixedStringMgr bloqueará o buffer fixo com um comprimento de zero. Desde que o comprimento da cadeia de caracteres não cresça além do tamanho do buffer fixo, CStringT não precisará realocar o buffer.

Se o tamanho solicitado da cadeia de caracteres for maior que o buffer fixo, CFixedStringMgr encaminhará a solicitação para o gerente de cadeias de caracteres de backup. Presume-se que o gerente de cadeias de caracteres de backup aloque o buffer do heap. No entanto, antes de retornar esse buffer, CFixedStringMgr bloqueia o buffer e substitui o ponteiro do gerente de cadeias de caracteres do buffer por um ponteiro para o objeto CFixedStringMgr. Isso garante que as tentativas de realocar ou liberar o buffer por CStringT chamem CFixedStringMgr.

Implementação de CFixedStringMgr::ReAllocate

A implementação de CFixedStringMgr::ReAllocate é muito semelhante à sua implementação de Allocate.

Se o buffer que está sendo realocado for o buffer fixo e o tamanho do buffer solicitado for menor que o buffer fixo, nenhuma alocação será feita. No entanto, se o buffer que está sendo realocado não for o buffer fixo, ele deverá ser um buffer alocado com o gerente de backup. Nesse caso, o gerente de backup é usado para realocar o buffer.

Se o buffer que está sendo realocado for o buffer fixo e o novo tamanho do buffer for muito grande para caber dentro do buffer fixo, CFixedStringMgr alocará um novo buffer usando o gerente de backup. O conteúdo do buffer fixo é copiado para o novo buffer.

Implementação de CFixedStringMgr::Free

A implementação de CFixedStringMgr::Free segue o mesmo padrão de Allocate e ReAllocate. Se o buffer que está sendo liberado for o buffer fixo, o método o definirá como um buffer bloqueado de comprimento zero. Se o buffer que está sendo liberado foi alocado com o gerente de backup, CFixedStringMgr usa o gerente de backup para liberá-lo.

Implementação de CFixedStringMgr::Clone

A implementação de CFixedStringMgr::Clone sempre retorna um ponteiro para o gerente de backup em vez do próprio CFixedStringMgr. Isso acontece porque todas as instâncias de CFixedStringMgr só podem ser associadas a uma única instância de CStringT. Qualquer outra instância de CStringT que tenta clonar o gerente deve obter o gerente de backup. Isso ocorre porque o gerente de backup dá suporte a ser compartilhado.

Implementação de CFixedStringMgr::GetNilString

A implementação de CFixedStringMgr::GetNilString retorna o buffer fixo. Devido à correspondência um a um de CFixedStringMgr e CStringT, uma determinada instância de CStringT nunca usa mais de um buffer por vez. Portanto, uma cadeia de caracteres zero e um buffer de cadeia de caracteres real nunca são necessários ao mesmo tempo.

Sempre que o buffer fixo não está em uso, CFixedStringMgr garante que ele seja inicializado com um comprimento zero. Isso permite que ele seja usado como a cadeia de caracteres zero. Como um bônus adicionado, o membro nAllocLength do buffer fixo sempre é definido como o tamanho total do buffer fixo. Isso significa que CStringT pode aumentar a cadeia de caracteres sem chamar IAtlStringMgr::Reallocate, mesmo para a cadeia de caracteres zero.

Requisitos

Cabeçalho: cstringt.h

Confira também

Gerenciamento de memória com CStringT