class — Для вектора указателей на объект, перераспределение вызывает удаление и копирование объектов?

Из моего понимания до сих пор, если у вас есть вектор объектов класса, если вы удаляете какой-либо элемент вектора, обычно вектор перераспределяет некоторые из своих объектов для сохранения смежности памяти. Следовательно, вам нужно реализовать правило трех (деструктор, конструктор копирования и оператор копирования) для всего, что будет сохранено при удалении векторных элементов.

Однако: для вектора указателей на объекты класса результат для меня менее ясен.
Если я удаляю член, то, несомненно, C ++ достаточно умен, чтобы просто копировать указатели вокруг — не сводя с ума удаляя указатель (и объект класса, на который он указывает), затем заново создайте его и объект, на который он указывает снова?

Если это не так, может кто-нибудь объяснить мне этот идиотизм?

1

Решение

Вектор будет удалять, конструировать и копировать любой тип, который он содержит. В случае вектора указателей на класс / структуру он будет удалять, создавать и копировать указатели, оставляя фактические объекты, на которые указывают указатели, в одиночку. Это зависит от вас, чтобы распределить и освободить их.


РЕДАКТИРОВАТЬ

Пример:

Если у вас есть следующее:

class A
{
A() {}
}

void foo(void)
{
A * pointerToA = new A;
}

В конце области видимости функции foo освобождается только память для переменной pointerToA само по себе, то есть 4 байта, которые содержат адрес (в 32-битном формате), который в этом случае хранится в стеке. Единственный способ освободить память, выделенную для нового экземпляра класса A, — это если вы вручную вызовете delete с адресом pointerToA,

Давайте возьмем пример массива класса A

A ** arrayOfPointerToA = new A*[10];
for(unsigned i = 0; i < 10; ++i)
arrayOfPointerToA[i] = new A;

что похоже на то, что происходит, когда у вас есть std::vector<A*>, Когда вы звоните

delete [] arrayOfPointerToA;

вы освобождаете память для массив указателей, не для каждого A,

введите описание изображения здесь

На приведенной выше диаграмме память, выделенная в результате вышеуказанного вызова для удаления, выделена красным. Обратите внимание, что каждый A хранится в случайном месте в памяти в этом случае, так как все они были выделены отдельно.

Теперь перенесем это в вектор:

std::vector<A> фактически использует новый A[size] выделить память. Если вы храните необработанный указатель, это будет означать, что он выделит массив типа A, что означает, что size количество объектов типа A созданы. Когда вектор освобождает свою память size количество объектов типа A уничтожены. Теперь возьмите этот пример и замените A на A *, и вы увидите, что ни один объект типа A не уничтожен.

Это фундаментальная часть работы C ++ и указателей, а не просто свойство контейнеров. Если бы контейнеры произвольно вызывали delete для каждого члена, это не имело бы смысла, как если бы у нас был контейнер A мы бы назвали delete для экземпляра объекта вместо указателя на этот объект, который недопустим.

1

Другие решения

Вектор оставит ваши значения указателя в покое. Конечно, он будет перемещать значения во внутреннем массиве при нажатии, выталкивании или удалении.

В этом случае значения являются просто указателями. Но в векторе нет логики, позволяющей определить, является ли что-то указателем на объект, и удалить / перераспределить их при копировании значений.

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

1

По вопросам рекламы [email protected]