более быстрое удаление векторного типа

0

Мой вопрос об оптимизации функции vector::erase.

Поскольку мы знаем, что вектор является непрерывным блоком памяти, а также знает каждый размер элемента в контейнере, почему метод vector<myclass> v erase(v.begin()) все еще вызывает все деструкторы элементов в v? Может ли это сделать пошаговую смену?

Пример: скажите, что у вас есть

//compiled with g++ 4.7
#include<iostream>
using namespace std;
class barebone{
public:
  ~barebone(){
    cout << "1" << endl;
  }
};

int main(){
    vector<barebone> x(5);
    x.erase(x.begin());
    cout << "done" << endl;
}

Это вызовет деструктор для каждого элемента в контейнере (5 раз). Это покажет 5. чересстрочный сдвиг будет быстрее и вызовет деструктор только один раз

EDIT: из деструктора вызова ответа delete() один раз с выходом

1 сделано 1 1 1 1

  • 0
    как насчет нетривиальных деструкторов?
  • 0
    в этом случае вы вызываете только деструктор первого элемента. но сделайте побайтовый сдвиг для остальных элементов.
Показать ещё 6 комментариев
Теги:
vector
stdvector

2 ответа

4
Лучший ответ

Деструктор должен быть вызван только для стирания элемента (ов); если вы видите, что это вызвано для других, то ваша реализация vector не соответствует. С++ 11 23.3.6.5 указывает

Сложность: деструктор T называется числом раз, равным числу стираемых элементов, но оператор назначения перемещения для T называется числом раз, равным числу элементов в векторе после стираемых элементов.

Старые стандарты указывали аналогичное поведение, но с копией, а не с перемещением.

Ваш пример показывает 1 пять раз, потому что остальные деструкторы вызываются, когда вектор уничтожается в конце main. Вы можете увидеть это более четко, если вы выведете что-то сразу после вызова для erase.

  • 0
    coliru.stacked-crooked.com/a/646ed396c66ff6ef для C ++ 03 Хотя это зависит от оператора присваивания. Если вы используете operator = (Foo other) вместо const Foo &other , временное значение будет уничтожаться каждый раз. Использование Foo other вместо const Foo &other было предложено в теме под названием What is the copy and swap idiom для некоторой оптимизации или w / e. В любом случае, +1 от меня. Я думал, что придется уничтожить все элементы, несмотря ни на что ..
0

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

#include <iostream>
#include <vector>

using namespace std;

class TestObject
{
    public:
    static int counter;
    TestObject()  { std::cout << "constructed!" << std::endl; }
    ~TestObject() { std::cout << "destructed!" << std::endl; counter++;}
};

int TestObject::counter = 0;

int main()
{
   std::vector<TestObject> to(5);
   to.erase(to.begin());
   std::cout << "destructed " << TestObject::counter << " times" << std::endl;

   to.push_back(TestObject());

   return 0;
}

Вот результат.

Компиляция исходного кода.... $g++ -std = С++ 11 main.cpp -o demo -lm -pthread -lgmpxx -lgmp -lreadline 2> & 1

Выполнение программы.... $ demo построено! построен! построен! построен! построен! подорванный! разрушено 1 раз построено! подорванный! подорванный! подорванный! подорванный! подорванный! подорванный!

Ясно, что деструктор выполняется один раз после удаления. Теперь, если у вас было стирание, как последнее, за которым следует cout в вашем собственном примере, возможно, что вы подумали, что он был уничтожен 5 раз стиранием.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню