Операторы доступа к элементам (точка и стрелка) не поддерживаются указателями unique_ptr на массивы. Другие его функции неизменны | |
|---|---|
unique_ptr | u может указывать на динамически созданный массив типа T |
unique ptr | u указывает на динамически созданный массив, на который указывает встроенный указатель p. Тип указателя p должен допускать приведение к типу T (см. раздел 4.11.2). Выражение u[i] возвратит объект в позиции i массива, которым владеет указатель u. u |
В отличие от указателя unique_ptr, указатель shared_ptr не оказывает прямой поддержки управлению динамическим массивом. Если необходимо использовать указатель shared_ptr для управления динамическим массивом, следует предоставить собственную функцию удаления:
//
//
shared_ptr
sp.reset(); //
//
Здесь лямбда-выражение (см. раздел 10.3.2), использующее оператор delete[], передается как функция удаления.
Если не предоставить функции удаления, результат выполнения этого кода непредсказуем. По умолчанию указатель shared_ptr использует оператор delete для удаления объекта, на который он указывает. Если объект является динамическим массивом, то при использовании оператора delete возникнут те же проблемы, что и при пропуске [], когда удаляется указатель на динамический массив (см. раздел 12.2.1).
Поскольку указатель shared_ptr не поддерживает прямой доступ к массиву, для обращения к его элементам применяется следующий код:
//
//
for (size_t i = 0; i != 10; ++i)
*(sp.get() + i) = i; //
//
Указатель shared_ptr не имеет оператора индексирования, а типы интеллектуальных указателей не поддерживают арифметических действий с указателями. В результате для доступа к элементам массива следует использовать функцию get(), возвращающую встроенный указатель, который можно затем использовать обычным способом.
Упражнение 12.23. Напишите программу, конкатенирующую два строковых литерала и помещающую результат в динамически созданный массив символов. Напишите программу, конкатенирующую две строки библиотечного типа string, имеющих те же значения, что и строковые литералы, используемые в первой программе.
Упражнение 12.24. Напишите программу, которая читает строку со стандартного устройства ввода в динамически созданный символьный массив. Объясните, как программа обеспечивает ввод данных переменного размера. Проверьте свою программу, введя строку, размер которой превышает длину зарезервированного массива.
Упражнение 12.25. С учетом следующего оператора new, как будет удаляться указатель pa?
int *pa = new int[10];
12.2.2. Класс allocator
Важный аспект, ограничивающий гибкость оператора new, заключается в том, что он объединяет резервирование памяти с созданием объекта (объектов) в этой памяти. Точно так же оператор delete объединяет удаление объекта с освобождением занимаемой им памяти. Обычно объединение инициализации с резервированием — это именно то, что и нужно при резервировании одиночного объекта. В этом случае почти наверняка известно значение, которое должен иметь объект.
Когда резервируется блок памяти, обычно в нем планируется создавать объекты по мере необходимости. В таком случае желательно было бы отделить резервирование памяти от создания объектов. Это позволит резервировать память в б
Зачастую объединение резервирования и создания оказывается расточительным. Например: