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