Я пытаюсь использовать std::vector
для хранения некоторых S
экземпляров.Однако, когда я переназначаю элемент вектора, деструктор не вызывается для предыдущего арендатора:
Код
#include <iostream>
#include <vector>
struct S {
int index_;
S(int index) : index_(index) {
std::cout << "Calling S " << index_ << " constructor\n";
}
S(const S& other) : index_(other.index_) {
std::cout << "Calling S " << index_ << " copy constructor\n";
}
~S() {
std::cout << "Calling S " << index_ << " destructor\n";
}
};
int main()
{
std::vector<S> v;
v.reserve(10); // Let's not worry about copy constructors
std::cout << "# Created vector\n";
v.emplace_back(0);
v.emplace_back(1);
v.emplace_back(2);
std::cout << "# Replacing\n";
v[1] = S(3); // This doesn't destruct S(1) that was here
// I can manually call the destructor before I reassign but is that
// something I should do()?
// v[1].~S();
std::cout << "# End scope\n";
}
Вывод
# Created vector
Calling S 0 constructor
Calling S 1 constructor
Calling S 2 constructor
# Replacing
Calling S 3 constructor
Calling S 3 destructor
# End scope
Calling S 2 destructor
Calling S 3 destructor
Calling S 0 destructor
Вопрос
Похоже, что S(1)
в позиции 1
никогда не разрушается.Как я отмечал в коде, я могу вручную вызвать деструктор, прежде чем переназначить его, но я не уверен, что это хорошая идея.Это так, и если нет, что вы предлагаете?Кроме того, есть ли
Соединения с тем, что я действительно хочу
В реальном коде я играю с бинарными деревьями, и я подумал, что было бы интересно сделать узлы членами вектора.и указывать друг на друга с помощью индексов в векторе (получая от меня непрерывные преимущества кэша памяти, 32-битные индексы вместо 64-битных указателей и что-то другое, с чем можно поиграть).Но в конце концов мне нужно выполнить некоторые операции с деревом, что означает перемещение / удаление элементов, поэтому я хочу, чтобы деструктор вызывался для удаления элемента (и я буду использовать std::set
или что-то еще, чтобы отслеживать дыры ввектор).