2017-02-10 25 views
2

Я пытаюсь понять, почему я получаю дополнительную операцию конструктора перемещения при добавлении объектов управления ресурсами в вектор.Почему я получаю операцию конструктора дополнительного перемещения при перемещении объектов в вектор?

Вот мой класс управления ресурсами:

class Resource 
{ 
public: 
    Resource() { 
     own_ = true; 
     id_ = next_id++; 
     std::cout << "Resource " << id_ << " constructed\n"; 
    } 

    Resource(Resource&& c) { 
     std::cout << "Move constructed from " << c.id_ << " to " << id_ << "\n"; 
     swap(*this, c); 
    } 

    ~Resource() { 
     if (own_) { 
      std::cout << "Resource " << id_ << " destructed\n"; 
     } 
    } 

    Resource& operator=(Resource&& c) { 
     std::cout << "Move assigned from " << c.id_ << " to " << id_ << "\n"; 
     swap(*this, c); 
     return *this; 
    } 

    void swap(Resource& a, Resource& b) { 
     std::swap(a.id_, b.id_); 
     std::swap(a.own_, b.own_); 
    } 

    Resource(Resource const&) = delete; 
    auto operator=(Resource const&)->Resource = delete; 
    static int next_id; 
private: 
    bool own_ = false; 
    int id_; 
}; 
int Resource::next_id = 1; 

И вот главная функция, где я создаю два объекта и перемещение их на мой вектор ресурсов:

int main() { 
    std::vector<Resource> resources; 

    Resource a, b; 
    resources.push_back(std::move(a)); 
    resources.push_back(std::move(b)); 

    return 0; 
} 

И вот вывод. Первые 4 строки похожи на то, что я ожидал от них, но последняя строка кажется дополнительной операцией, так как что-то перестраивается или сортируется внутри вектора. Конечное содержание вектора, как и ожидалось, - это 2 ресурсных объекта, но мой выход:

Resource 1 constructed 
Resource 2 constructed 
Move constructed from 1 to -842150451 
Move constructed from 2 to -842150451 
Move constructed from 1 to -842150451 
+0

http://stackoverflow.com/questions/23717151/why-emplace-back-is-faster-than-push-back –

+0

Обратите внимание, что если ваш конструктор копирования не был 'delete'd, у вас было бы только видел 2 перемещения конструкций, но для [совершенно другой причины] (http://stackoverflow.com/q/8001823/241631). – Praetorian

+0

Мой последний комментарий должен был сказать, если ваш конструктор копирования был 'default' (поскольку он неявно удаляется в любом случае). – Praetorian

ответ

4

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

Обычно, когда у вас есть пустой вектор, push_pack выделит 1 место хранения и добавит в него элемент. Затем при следующем вызове push_back он будет выделять новое хранилище с удвоенной емкостью и перемещать/копировать все из старого хранилища в новое хранилище. Каждый раз, когда вы вызываете push_back, если size() == capacity(), тогда вектор должен выделить новое хранилище и переместить все в новое хранилище, а затем добавить новый элемент.

 Смежные вопросы

  • Нет связанных вопросов^_^