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


Реализация пользовательского диспетчера строк (расширенный метод)

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

Для этого важно сначала понять, как CStringT использует этот интерфейс для управления строковыми данными. Каждый экземпляр CStringT имеет указатель на структуру CStringData . Эта структура переменной длины содержит важные сведения о строке (например, длине), а также фактические символьные данные для строки. Каждый пользовательский диспетчер строк отвечает за выделение и освобождение этих структур по запросу CStringT.

Структура CStringData состоит из четырех полей:

  • PStringMgr Это поле указывает на интерфейс, IAtlStringMgr используемый для управления данными строки. Если CStringT необходимо перераспределить или освободить буфер строки, который вызывает методы Reallocate или Free этого интерфейса, передав структуру CStringData в качестве параметра. При выделении CStringData структуры в диспетчере строк необходимо задать это поле для указания пользовательского диспетчера строк.

  • nDataLength Это поле содержит текущую логическую длину строки, хранящейся в буфере, за исключением конца null. CStringT обновляет это поле при изменении длины строки. При выделении CStringData структуры диспетчер строк должен задать это поле равным нулю. При перемещении структуры настраиваемый CStringData диспетчер строк должен оставить это поле неизменным.

  • NAllocLength Это поле содержит максимальное количество символов (за исключением конца NULL), которое можно хранить в этом буфере строки без перераспределения. Каждый раз CStringT , когда необходимо увеличить логическую длину строки, сначала проверяет это поле, чтобы убедиться, что в буфере достаточно места. Если проверка завершается ошибкой, вызовы в пользовательский диспетчер строк для CStringT перераспределации буфера. При выделении или перемещении CStringData структуры необходимо задать по крайней мере количество символов, запрошенных в параметре nChars , значение IAtlStringMgr::Allocate или IAtlStringMgr::Reallocate. Если в буфере больше места, чем запрошено, можно задать это значение, чтобы отразить фактическое количество свободного места. Это позволяет CStringT увеличить строку для заполнения всего выделенного пространства, прежде чем он должен вернуться в диспетчер строк, чтобы перераспределить буфер.

  • nRefs Это поле содержит текущее число ссылок буфера строки. Если значение равно одному, то один экземпляр CStringT использует буфер. Кроме того, экземпляр может читать и изменять содержимое буфера. Если значение больше одного, несколько экземпляров CStringT могут использовать буфер. Так как буфер символов является общим, CStringT экземпляры могут считывать только содержимое буфера. Чтобы изменить содержимое, CStringT сначала создайте копию буфера. Если значение отрицательное, используется только один экземпляр CStringT буфера. В этом случае буфер считается заблокированным. CStringT Если экземпляр использует заблокированный буфер, другие экземпляры CStringT не могут совместно использовать буфер. Вместо этого эти экземпляры создают копию буфера перед обработкой содержимого. Кроме того, экземпляр, использующий заблокированный буфер, CStringT не пытается совместно использовать буфер любого другого CStringT экземпляра, назначенного ему. В этом случае CStringT экземпляр копирует другую строку в заблокированный буфер.

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

См. также

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