Pop back c что делает
Перейти к содержимому

Pop back c что делает

  • автор:

Реализация pop_back для вектора

Собственно, что вам нужно? просто указать, что элементов стало на один меньше. Зачем при этом уменьшать выделенную память? Пусть себе ждет вставки нового элемента. Ну и, конечно, нужно убедиться, что сам вектор в этот момент не пустой, т.е.

if (mSize) --mSize; 

Другое дело — вызывать ли деструктор для элемента явно или оставить элемент как есть. Это зависит от того, как именно вы работаете с элементами — добавляете новый путем вызова конструктора копирования или при помощи присваивания.

Отслеживать
ответ дан 26 дек 2017 в 8:58
218k 15 15 золотых знаков 117 117 серебряных знаков 229 229 бронзовых знаков
да мне нужно через деструктор удалять
26 дек 2017 в 9:03

Ну, тогда дополнительно удаляете вызовом деструктора, только учтите, что при удалении потом delete[]mVector; деструкторы будут вызваны повторно. Ну и в push_back вы тогда не должны использовать присваивание — потому что при этом опять же в этом элементе после деструктора уже нет нормального объекта.

26 дек 2017 в 9:06
а как мне вызывать деструктор последнего элемента? который я хочу удалить
26 дек 2017 в 9:07
@ОксанаВолинець, mVector[mSize-1].~T();
26 дек 2017 в 9:09

Один из вариантов выглядит так:

template void Vector::PopBack() < if(isEmpty())< return; >--mSize; mVector[mSize].~T(); > 

Но если вы планируете вызывать деструктор явно, то вам следует пересмотреть алгоритм выделения/освобождения памяти. Так как new T[] / delete[] может привести к повторному вызову деструктора.

В общих чертах, это могло бы выглядеть так:

template class Vector < int mSize; int mCapacity; T *mVector; public: Vector(): mSize(0), mCapacity(42), mVector(allocate(mCapacity)) <>T* begin() < return mVector; >T* end() < return mVector + mSize; >bool isEmpty() const < return mSize == 0; >void popBack() < if(isEmpty())< return; >--mSize; destroy(end()); > ~Vector() < for(T &object : *this)< destroy(&object); >deallocate(mVector); > private: static void construct(T *object) < new(object) T; >static void destroy(T *object)< object->~T(); > static T* allocate(int count)< return static_cast(malloc(count * sizeof(T))); > static void deallocate(void *ptr) < free(ptr); >>; 

Как видите, вся работа с выделением/освобождением памяти происходит в методах allocate / deallocate . В методе allocate выделяется кусок памяти при помощи malloc . В методе deallocate этот кусок памяти освобождается. Никаких конструкторов и деструкторов автоматически не вызывается. Эти операции нам придется делать вручную. Для этих целей есть методы construct / destroy .

Конструктор, деструктор, и метод popBack в этом примере реализованы. Аналогично при помощи методов allocate , deallocate , construct и destroy можно реализовать остальные.

P.S. Кстати, примерно таким же образом работает с памятью стандартный вектор. Только у него все эти методы вынесены в отдельный класс std::allocator . Но вам для простоты можно объявить их прямо в теле вектора.

Реализовать операцию pop_front для вектора на C++

Напишите код для реализации pop_front операция для вектора в C++. pop_front операция должна удалить первый элемент из вектора и сохранить порядок остальных элементов.

Мы знаем это std::vector поддерживает только push_back а также pop_back операции. Обе операции выполняются за постоянное время. pop_front операция займет не менее O(n) время, так как vector поддерживается массивом, и все оставшиеся элементы должны быть сдвинуты на одну позицию влево, чтобы сохранить порядок. Если общее количество pop_front операций больше, тем std::list следует отдавать предпочтение контейнеру, реализованному в виде двусторонней queue (deque).

Так pop_front операция займет линейное время и должна вызываться только в том случае, если vector содержит всего несколько элементов. Вот одна возможная реализация pop_front функция, которая просто стирает первый элемент вектора, используя vector::erase функция. vector::erase функции требуется итератор, указывающий на элемент, который нужно удалить из вектора, и мы можем получить итератор для первого элемента вектора, вызвав vector::begin .

Pop back c что делает

Для добавления элементов в вектор применяется функция push_back() , в которую передается добавляемый элемент:

#include #include int main() < std::vectornumbers; // пустой вектор numbers.push_back(5); numbers.push_back(3); numbers.push_back(10); for(int n : numbers) cout << n << "\t"; // 5 3 10 std::cout

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

Функция emplace_back() выполняет аналогичную задачу — добавляет элемент в конец контейнера:

std::vector numbers< 1, 2, 3, 4, 5 >; numbers.emplace_back(8); // numbers = < 1, 2, 3, 4, 5, 8 >;

Добавление элементов на определенную позицию

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

  • emplace(pos, value) : вставляет элемент value на позицию, на которую указывает итератор pos
  • insert(pos, value) : вставляет элемент value на позицию, на которую указывает итератор pos, аналогично функции emplace
  • insert(pos, n, value) : вставляет n элементов value начиная с позиции, на которую указывает итератор pos
  • insert(pos, begin, end) : вставляет начиная с позиции, на которую указывает итератор pos, элементы из другого контейнера из диапазона между итераторами begin и end
  • insert(pos, values) : вставляет список значений начиная с позиции, на которую указывает итератор pos
std::vector numbers< 1, 2, 3, 4, 5 >; auto iter = numbers.cbegin(); // константный итератор указывает на первый элемент numbers.emplace(iter + 2, 8); // добавляем после второго элемента numbers = < 1, 2, 8, 3, 4, 5>;
std::vector numbers1< 1, 2, 3, 4, 5 >; auto iter1 = numbers1.cbegin(); // константный итератор указывает на первый элемент numbers1.insert(iter1 + 2, 8); // добавляем после второго элемента //numbers1 = < 1, 2, 8, 3, 4, 5>; std::vector numbers2 < 1, 2, 3, 4, 5 >; auto iter2 = numbers2.cbegin(); // константный итератор указывает на первый элемент numbers2.insert(iter2 + 1, 3, 4); // добавляем после первого элемента три четверки //numbers2 = < 1, 4, 4, 4, 2, 3, 4, 5>; std::vector values < 10, 20, 30, 40, 50 >; std::vector numbers3 < 1, 2, 3, 4, 5 >; auto iter3 = numbers3.cbegin(); // константный итератор указывает на первый элемент // добавляем после первого элемента три первых элемента из вектора values numbers3.insert(iter3 + 1, values.begin(), values.begin() + 3); //numbers3 = < 1, 10, 20, 30, 2, 3, 4, 5>; std::vector numbers4 < 1, 2, 3, 4, 5 >; auto iter4 = numbers4.cend(); // константный итератор указывает на позицию за последним элементом // добавляем в конец вектора numbers4 элементы из списка < 21, 22, 23 >numbers4.insert(iter4, < 21, 22, 23 >); //numbers4 = < 1, 2, 3, 4, 5, 21, 22, 23>;

Удаление элементов

Если необходимо удалить все элементы вектора, то можно использовать функцию clear :

std::vector v < 1,2,3,4 >; v.clear();

Функция pop_back() удаляет последний элемент вектора:

std::vector v < 1,2,3,4 >; v.pop_back(); // v =

Если нужно удалить элемент из середины или начала контейнера, применяется функция std::erase() , которая имеет следующие формы:

  • erase(p) : удаляет элемент, на который указывает итератор p. Возвращает итератор на элемент, следующий после удаленного, или на конец контейнера, если удален последний элемент
  • erase(begin, end) : удаляет элементы из диапазона, на начало и конец которого указывают итераторы begin и end. Возвращает итератор на элемент, следующий после последнего удаленного, или на конец контейнера, если удален последний элемент

std::vector numbers1 < 1, 2, 3, 4, 5, 6 >; auto iter = numbers1.cbegin(); // указатель на первый элемент numbers1.erase(iter + 2); // удаляем третий элемент // numbers1 = < 1, 2, 4, 5, 6 >std::vector numbers2 = < 1, 2, 3, 4, 5, 6 >; auto begin = numbers2.cbegin(); // указатель на первый элемент auto end = numbers2.cend(); // указатель на последний элемент numbers2.erase(begin + 2, end — 1); // удаляем с третьего элемента до последнего // numbers2 =

Также начиная со стандарта С++20 в язык была добавлена функция std::erase() . Она не является частью типа vector. В качестве первого параметра она принимает вектор, а в качестве второго — элемент, который надо удалить:

std::vector numbers3 < 1, 2, 3, 1, 5, 6 >; std::erase(numbers3, 1); // numbers3 =

В данном случае удаляем из вектора numbers3 все вхождения числа 1.

Размер вектора

С помощью функции size() можно узнать размер вектора, а с помощью функции empty() проверить, путой ли вектор:

#include #include int main() < std::vectornumbers; if(numbers.empty()) std::cout

С помощью функции resize() можно изменить размер вектора. Эта функция имеет две формы:

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

std::vector numbers1 < 1, 2, 3, 4, 5, 6 >; numbers1.resize(4); // оставляем первые четыре элемента — numbers1 = numbers1.resize(6, 8); // numbers1 =

Важно учитывать, что применение функции resize может сделать некорректными все итераторы, указатели и ссылки на элементы.

Изменение элементов вектора

Функция assign() позволяет заменить все элементы вектора определенным набором:

std::vector langs = < "Java", "JavaScript", "C">; langs.assign(4, «C++»); // langs =

В данном случае элементы вектора заменяются набором из четырех строк «C++».

Также можно передать непосредственно набор значений, который заменит значения вектора:

std::vector langs< "Java", "JavaScript", "C">; langs.assign(< "C++", "C#", "C">); // langs =

Еще одна функция — swap() обменивает значения двух контейнеров:

std::vector clangs < "C++", "C#", "Java" >; std::vector ilangs < "JavaScript", "Python", "PHP">; clangs.swap(ilangs); // clangs = < "JavaScript", "Python", "PHP">; for(std::string lang : clangs)

Сравнение векторов

Векторы можно сравнивать — они поддерживают все операции сравнения: , =, ==, !=. Сравнение контейнеров осуществляется на основании сравнения пар элементов на тех же позициях. Векторы равны, если они содержат одинаковые элементы на тех же позициях. Иначе они не равны:

std::vector v1 ; std::vector v2 ; std::vector v3 ; bool v1v2 = v1 == v2; // true bool v1v3 = v1 != v3; // true bool v2v3 = v2 == v3; // false

Отличие erase() и pop_back() при работе с std::vector

При использовании функций ersae() и pop_back() происходит различие по времени исполнения операции. Как устроены и асимптотически отличаются эти 2 строчки?

1 2 3 4 5 6 7 8 9 10 11 12 13
#include #include using namespace std; vector int> v; int main() { v={1, 2}; v.pop_back(); v.erase(v.begin()); return 0; }

Лучшие ответы ( 1 )
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:

Ошибка при использовании erase для std::vector
Почему в случае удаления элемента из вектора с помощью передачи итератора в erase, который.

Ошибка “vector erase iterator outside range” при работе алгоритма Хаффмана
Проблема с функцией BuildTable. Компилируется, но в процессе работы возникает ошибка. //.

std::vector::erase
Всем привет. Буду очень рад, если кто-нибудь может мне объяснить логику. см. скриншот.

На основе исходного std::vector содержащего числа, создать std::vector с этими же числами
подскажите есть вот такая задача. Есть список . Создать второй список, в котором будут все эти же.

Неэпический
17849 / 10617 / 2049
Регистрация: 27.09.2012
Сообщений: 26,686
Записей в блоге: 1

Лучший ответ

Сообщение было отмечено Syjxs как решение

Решение

v.pop_back();

Удаляет элемент с конца вектора.
Т.к. элементы типа int, то можно просто уменьшить размер вектора на единицу.
Сложность — O(1).

v.erase(v.begin());

Элемент удаляется из начала вектора.
Значит нужно все оставшиеся элементы сдвинуть на один к началу.
Сложность — O(N).

87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь

Крах при vector.erase()
Всё вроде бы работает так, как мне надо. но когда остаётся 1 элемент и его нужно очистить.

Как передать целочисленную матрицу типа std::vector > в функцию?
Здравствуйте. Почитал на форуме, но так и не понял что я делаю не так. Имеется двумерный вектор.

stl::vector, метод pop_back()
Доброго времени суток! Вот такой вопрос: я создаю объект в куче: someClass *test =.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *