Выделение (и вызов деструктора) аргумента шаблона

контекст

Я пытаюсь реализовать мою версию std::vector шаблон класса. Вектор содержит динамический массив аргумента шаблона T:

_vec = new T[n];

очевидно T может быть любого типа, указатели, классы, примитивные типы. Когда один звонок v.resize(4) на вектор размера 6 очевидно, он должен удалить последние 2 элемента динамического массива (без перераспределения массива) после эта спецификация:

Если n меньше текущего размера контейнера, содержимое сокращается до его первых n элементов, удаляя те, которые находятся за ними (и уничтожая их).

От разрушающий Я имею в виду, и я думаю, что библиотека std означает вызов деструктора для объекта или просто освобождение пространства памяти, если это любой другой примитивный тип, включая указатели.

Вопрос: Возможно ли (и если да, то как) уничтожить элементы шаблона в динамически распределенном массиве без его освобождения и перераспределения?

Что я пробовал? Ну, я искренне не знаю, с чего начать

  • По-видимому ты не должен позвонить delete на примитивных типах.
  • Вы можете явно вызвать деструктор для объекта, но это не сработает, если T это не объект.
  • Я думал просто уменьшить внутреннее _size счетчик (так что будущее push_back элементы будут перезаписаны), но это не сразу вызовет деструктор для объекта.

1

Решение

Когда вы реализуете vectorВы, вероятно, хотите разделить управление хранилищем и управление объектами.

Хранение управляется с помощью allocator::allocate(size_type n) а также allocator::deallocate(pointer p, size_type n)которые обычно реализуются как return ::operator new(n * sizeof (T)); а также ::operator delete(p); соответственно.

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

Время жизни объекта управляется с помощью allocator::construct(U* p, Args&&... args); а также allocator::destroy(U* p);которые обычно реализуются как ::new((void *)p) U(std::forward<Args>(args)...); а также p->~U() соответственно.

Эти функции создают и деконструируют объекты в предварительно выделенной памяти, но сами не управляют памятью.

2

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

new T[n] это не то, что вы хотите, потому что это уже создаст n объекты типа T, но вы хотите только выделить объем памяти до n объекты типа T,

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

1

FredOverflow прав насчет размещения объектов.

В соответствии с вашим вопросом, все, что вам нужно сделать, это просто отличить объекты от не-объектов (скаляры). Есть реальный код от <xmemory> в выпуске Visual Studio 2010:

template<class _Alloc> inline void _Destroy_range(
typename _Alloc::pointer _First, typename _Alloc::pointer _Last, _Alloc& _Al);

template<class _Alloc> inline void _Destroy_range(
typename _Alloc::pointer _First, typename _Alloc::pointer _Last, _Alloc& _Al,
_Nonscalar_ptr_iterator_tag);  // Object overload

template<class _Alloc> inline void _Destroy_range(
typename _Alloc::pointer _First, typename _Alloc::pointer _Last, _Alloc& _Al,
_Scalar_ptr_iterator_tag);  // Non-object overload

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

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