В языке программирования С++ Edition 4 приведен пример реализации вектора, см. соответствующий код в конце сообщения.
uninitialized_move() инициализирует новые объекты T в новую область памяти, перемещая их из старой области памяти. Затем он вызывает деструктор на исходном объекте T, перемещенном объекте. Почему в этом случае необходим вызов деструктора?
Вот мое неполное понимание: перемещение объекта означает, что право собственности на ресурсы, принадлежащие перемещенному объекту, передается перемещенному объекту. Остатки в перемещенном объекте являются некоторыми возможными элементами встроенных типов, которые не нужно уничтожать, они будут освобождены, когда вектор_база b выходит из области видимости (внутри reserve(), после вызова swap()). Все указатели в перемещенном объекте должны быть помещены в nullptr или используется какой-либо механизм для отказа от права собственности на перемещенный объект из этих ресурсов, чтобы мы были в безопасности, а затем зачем вызывать деструктор на обедненном объекте, когда "vector_base b" destructor все равно освободит память после завершения обмена?
Я понимаю необходимость явного вызова деструктора в случаях, когда он должен быть вызван, потому что у нас есть что-то разрушить (например, элементы drop), но я не вижу его значения после std:: move + deallocation vector_base. Я прочитал несколько текстов в сети, и я вижу деструкторный вызов перемещенного объекта как сигнал (кому или что?), Что срок жизни объекта завершен.
Прошу пояснить мне, какая значимая работа еще предстоит сделать деструктору? Спасибо!
Ниже приведен фрагмент кода http://www.stroustrup.com/4th_printing3.html
template<typename T, typename A>
void vector<T,A>::reserve(size_type newalloc)
{
if (newalloc<=capacity()) return; // never decrease allocation
vector_base<T,A> b {vb.alloc,size(),newalloc-size()}; // get new space
uninitialized_move(vb.elem,vb.elem+size(),b.elem); // move elements
swap(vb,b); // install new base
} // implicitly release old space
template<typename In, typename Out>
Out uninitialized_move(In b, In e, Out oo)
{
using T = Value_type<Out>; // assume suitably defined type function (_tour4.iteratortraits_, _meta.type.traits_)
for (; b!=e; ++b,++oo) {
new(static_cast<void*>(&*oo)) T{move(*b)}; // move construct
b->~T(); // destroy
}
return oo;
}