Поделиться через


CFixedStringT. Пример пользовательского диспетчера строк

Библиотека ATL реализует один из примеров пользовательского диспетчера строк, используемого классом CFixedStringT с именем CFixedStringMgr. CFixedStringT является производным от CStringT и реализует строку, которая выделяет свои символьные данные как часть CFixedStringT самого объекта, если строка меньше длины, указанной параметром t_nChars CFixedStringTшаблона. При таком подходе строка не нуждается в куче вообще, если длина строки не превышает размер фиксированного буфера. Так как CFixedStringT не всегда использует кучу для выделения строковых данных, она не может использоваться CAtlStringMgr в качестве диспетчера строк. В нем используется пользовательский диспетчер строк (CFixedStringMgr), реализующий интерфейс IAtlStringMgr . Этот интерфейс рассматривается в реализации пользовательского диспетчера строк (расширенный метод).

Конструктор для CFixedStringMgr трех параметров:

  • pData: указатель на фиксированную CStringData структуру, которую следует использовать.

  • nChars: максимальное количество символов, которые CStringData может содержать структура.

  • pMgr: указатель на IAtlStringMgr интерфейс "диспетчера строк резервного копирования".

Конструктор сохраняет значения pData и pMgr в соответствующих переменных-членах (m_pDataиm_pMgr). Затем он задает длину буфера равным нулю, доступной длине, равной максимальному размеру фиксированного буфера, а число ссылок — -1. Значение счетчика ссылок указывает, что буфер заблокирован и используется этот экземпляр в качестве диспетчера CFixedStringMgr строк.

Помечая буфер как заблокированный, другие CStringT экземпляры не будут хранить общую ссылку на буфер. Если другим CStringT экземплярам было разрешено предоставить общий доступ к буферу, можно было бы удалить буфер, содержащийся CFixedStringT в то время как другие строки по-прежнему используют буфер.

CFixedStringMgr является полной реализацией IAtlStringMgr интерфейса. Реализация каждого метода рассматривается отдельно.

Реализация CFixedStringMgr::Allocate

Реализация первых CFixedStringMgr::Allocate проверок, чтобы узнать, равен ли запрошенный размер строки меньше или равен размеру фиксированного буфера (хранящегося в элементе m_pData ). Если фиксированный буфер достаточно велик, CFixedStringMgr блокирует фиксированный буфер с нулевой длиной. Если длина строки не превышает размер фиксированного буфера, CStringT не придется перераспределять буфер.

Если запрошенный размер строки больше фиксированного буфера CFixedStringMgr перенаправит запрос в диспетчер строк резервного копирования. Предполагается, что диспетчер строк резервной копии выделяет буфер из кучи. Однако перед возвратом этого буфера буфер CFixedStringMgr блокирует буфер и заменяет указатель диспетчера строк буфера указателем на CFixedStringMgr объект. Это гарантирует, что попытки перераспределить или освободить буфер путем CStringT вызова CFixedStringMgr.

Реализация CFixedStringMgr::ReAllocate

CFixedStringMgr::ReAllocate Реализация очень похожа на ее реализациюAllocate.

Если буфер перераспределен, является фиксированным буфером, а запрошенный размер буфера меньше фиксированного буфера, выделение не выполняется. Однако если перераспределенный буфер не является фиксированным буфером, он должен быть буфером, выделенным диспетчером резервных копий. В этом случае диспетчер резервного копирования используется для перераспределирования буфера.

Если буфер перераспределен, это фиксированный буфер, а новый размер буфера слишком велик, чтобы поместиться в фиксированный буфер, CFixedStringMgr выделяет новый буфер с помощью диспетчера резервных копий. Затем содержимое фиксированного буфера копируется в новый буфер.

Реализация CFixedStringMgr::Free

CFixedStringMgr::Free Реализация соответствует тому же шаблону, что Allocate и ReAllocate. Если буфер освобождается является фиксированным буфером, метод задает для него заблокированный буфер нулевой длины. Если буфер, освобожденный, был выделен диспетчером резервных копий, CFixedStringMgr использует диспетчер резервного копирования для его освобождения.

Реализация CFixedStringMgr::Clone

Реализация CFixedStringMgr::Clone всегда возвращает указатель на диспетчер резервного копирования, а не сам.CFixedStringMgr Это происходит, так как каждый экземпляр CFixedStringMgr может быть связан только с одним экземпляром CStringT. Любые другие экземпляры CStringT попытки клонировать руководителя должны вместо этого получить диспетчер резервного копирования. Это связано с тем, что диспетчер резервного копирования поддерживает общий доступ.

Реализация CFixedStringMgr::GetNilString

Реализация возвращает фиксированный CFixedStringMgr::GetNilString буфер. Из-за одно-соответствия CFixedStringMgr и CStringT, заданный экземпляр CStringT никогда не использует несколько буферов одновременно. Таким образом, строка nil и реальный буфер строк никогда не требуются одновременно.

Всякий раз, когда фиксированный буфер не используется, CFixedStringMgr гарантирует, что он инициализирован с нулевой длиной. Это позволяет использовать его в качестве строки nil. В качестве дополнительного бонуса nAllocLength член фиксированного буфера всегда устанавливается на полный размер фиксированного буфера. Это означает, что CStringT строка может расти без вызова IAtlStringMgr::Reallocate, даже для строки nil.

Требования

Заголовок: cstringt.h

См. также

Управление памятью с помощью CStringT