Строки. Размер и емкость

   
На этом шаге мы рассмотрим методы, используемые для работы с этими параметрами строк.

   
Чтобы правильно и эффективно использовать строки, необходимо хорошо понимать, как связаны их размер и емкость. Для строк существуют целых
три "размера".

  • size() и length(). Эти функции возвращают количество символов в строке и являются эквивалентными.   Замечание.
    В данном случае эквивалентность функций объясняется тем, что length() возвращает длину строки по аналогии с функцией strlen() для
    обычных С-строк, а функция size() поддерживается всеми контейнерными классами и возвращает количество элементов в соответствии
    с архитектурными канонами STL.

       
    Функция empty() проверяет, равно ли количество символов нулю (то есть является ли строка пустой). По возможности используйте ее вместо
    функций length() и size(), поскольку эта функция может работать быстрее.

  • max_size(). Эта функция возвращает максимальное количество символов, которые могут содержаться в строке. Обычно все символы
    строки хранятся в одном блоке памяти, что может привести к дополнительным ограничениям. В остальных случаях это значение обычно равно
    максимальному значению типа индекса, уменьшенному на 1. Единица вычитается по двум причинам: во-первых, максимальное значение представляет
    npos, и, во-вторых, реализация может дописать \0 в конец внутреннего буфера, чтобы при преобразовании строки в формат С-строк
    (например, при вызове c_str()) можно было просто вернуть этот буфер. Если в результате операции должна быть создана строка, длина
    которой превышает max_size(), класс генерирует исключение length_error.
  • capacity(). Эта функция возвращает емкость строки, то есть количество символов, которые можно сохранить в строке без перераспределения ее внутренней памяти.

   
Достаточная емкость строки важна по двум причинам:

  • в результате перераспределения памяти становятся недействительными все ссылки, указатели и итераторы, ссылающиеся на символы строки;
  • на перераспределение памяти тратится время.

   
Следовательно, если в программе используются указатели, ссылки и итераторы, относящиеся к символам строки, или если программа критична по
скорости, следует учитывать ее емкость.

   
Функция reserve() помогает предотвратить перераспределение памяти. Она заранее резервирует нужную емкость и обеспечивает
действительность ссылок (при условии, что размер строки не превышает зарезервированную емкость):

std::string s;   // Создание пустой строки 
s.reserve(80);   // Резервирование памяти для 80 символов

   
В принципе концепция емкости для строк похожа на концепцию емкости векторов (смотри 130 шаг), но с одним важным
отличием: строки позволяют вызывать функцию reserve() для сокращения емкости. Вызов reserve() с аргументом, меньшим текущей
емкости, фактически является запросом на сокращение емкости, не обязательным для выполнения. Если аргумент меньше текущего количества символов,
то емкость сокращается до текущего размера строки. Следовательно, даже если вы хотите сократить емкость, вызов функции еще не гарантирует
желаемого результата. По умолчанию аргумент функции reserve() для строк равен нулю. Следовательно, вызов reserve() без
аргументов всегда означает запрос на сокращение емкости до текущего размера строки, но этот запрос не обязателен для выполнения:

s.reserve(); // Запрос на сокращение емкости до текущего размера

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

   
Тем не менее в стандарте указано, что емкость строки может уменьшаться только вследствие вызова функции reserve(). Это гарантирует,
что ссылки, указатели и итераторы останутся действительными даже при удалении и изменении символов (если они относятся к позициям,
предшествующим позиции модификации).

   
На следующем шаге мы рассмотрим способы обращения к символам строки.



Вы можете оставить комментарий, или Трекбэк с вашего сайта.

Оставить комментарий