//
//
std::pair
(const std::string*, const std::string*);
void free(); //
void reallocate(); //
//
std::string *elements; //
std::string *first_free; //
//
std::string *cap; //
//
};
Тело класса определяет некоторые из своих членов.
• Стандартный конструктор (неявно) инициализирует по умолчанию переменную-член alloc и (явно) инициализирует указатели как nullptr, означая, что никаких элементов нет.
• Функция-член size() возвращает количество фактически используемых элементов, соответствует значению first_free - elements.
• Функция-член capacity() возвращает количество элементов, которые может содержать объект класса StrVec, соответствует значению cap - elements.
• Функция-член chk_n_alloc() приводит к пересозданию объекта класса StrVec, когда больше нет места для добавления следующего элемента. Это происходит при cap == first_free.
• Функции-члены begin() и end() возвращают указатели на первый (т.е. elements) и следующий после последнего существующего элемент (т.е. first_free) соответственно.
construct()Функция push_back() вызывает функцию chk_n_alloc(), чтобы удостовериться в наличии места для элемента. В случае необходимости функция chk_n_alloc() вызовет функцию reallocate(). После вызова функции chk_n_alloc() функция push_back() знает, что место для нового элемента есть. Она запрашивает свой член класса allocator создать новый последний элемент:
void StrVec::push_back(const string& s) {
chk_n_alloc(); //
//
alloc.construct(first_free++, s);
}
При использовании класса allocator для резервирования памяти следует помнить, что память резервируется пустой (см. раздел 12.2.2). Чтобы использовать эту память, следует вызвать функцию construct(), которая создаст объект в этой памяти. Первый аргумент функции construct() — это указатель на пустое пространство, зарезервированное вызовом функции allocate(). Остальные аргументы определяют, какой конструктор использовать при создании объекта в этом пространстве. В данном случае есть только один дополнительный аргумент типа string, поэтому этот вызов использует строковый конструктор копий.
Следует заметить, что вызов функции construct() осуществляет приращение указателя first_free, чтобы он снова указывал на элемент, который предстоит создать. Поскольку используется постфиксный инкремент (см. раздел 4.5), этот вызов создает объект в текущей позиции указателя first_free, а инкремент переводит его на следующий пустой элемент.
alloc_n_copy()Функция-член alloc_n_copy() вызывается при копировании или присвоении объекта класса StrVec. У класса StrVec будет подобное значению поведение (см. раздел 13.2.1), как у вектора; при копировании или присвоении объекта класса StrVec необходимо зарезервировать независимую память и скопировать элементы из оригинала в новый объект класса StrVec.
Функция-член alloc_n_copy() будет резервировать достаточно места для содержания заданного диапазона элементов, а затем копировать эти элементы во вновь созданное пространство. Эта функция возвращает значение типа pair (см. раздел 11.2.3), переменные-члены которого являются указателем на начало нового пространства и следующую позицию после последнего скопированного элемента:
pair
StrVec::alloc_n_copy(const string *b, const string *e) {
//
auto data = alloc.allocate(е - b);