Почему здесь не просто удаляется нулевой элемент вектора, а еще и заменяется значение второго?
Почему в данном коде, после строки v.erase(v.begin()); не просто удаляется нулевой элемент вектора, а еще и заменяется значение второго.
class A
{
public:
int* p;
A() : p() {}
A(int _) : p(new int(_)) {}
A(const A& a) {
p = new int(*a.p);
}
virtual ~A() {
delete p;
}
};
void dump(const A& a)
{
std::cout << *a.p << std::endl;
}
int main()
{
std::vector<A> v;
v.push_back(A(1));
v.push_back(A(2));
v.push_back(A(3));
v.erase(v.begin());
std::for_each(v.begin(), v.end(), dump);
std::cin.get();
return 0;
}
Вывод
2
-2054136144
Ответы (2 шт):
Представим себе строй солдат - значений в векторе.
Ррррассчитайсь!
Первый-второй-третий-...
Первого враги выводят и расстреливают. Ну, или начальство награждает и демобилизует. Неважно! Важно, что в строю его больше нет...
Ррррассчитайсь!
Первый-второй-третий-...
И кто теперь крикнет "первый"?
Только вот строй такой, что никто не умеет правильно делать шаг влево :) - нет оператора присваивания... Вот они при попытке сомкнуть строй просто падают. А поскольку освобождение места в строю сопровождается освобождением памяти - то проблемы поверхностного копирования становятся слишком глубокими :)
Вопросов больше нет?
Допишите в класс вот такой оператор -
A& operator=(const A& a) {
cout << "===\n";
delete p;
p = new int(*a.p);
return *this;
}
(вывод - чтоб вы видели, когда он вызывается) и посмотрите на результат.
Вообще говоря, для поддержки всех операций вектор требует, чтобы тип был как CopyConstructable, так и CopyAssignable, т.е. в нём применяется operator=(), а т.к. ты нарушил правило трёх, то operator=() по умолчанию делает глупость просто копируя указатель. Надо просто явно его определить:
A& operator=(const A& a) {
delete p;
p = new int(*a.p);
return *this;
}