2014-02-08 3 views
8

У меня есть класс с удаленной копией ctor и деструктор, который освобождает ресурс C.Почему emplace_back вызывает деструктор?

Я бы ожидал, что emplace_back переместит объекты и вызовет деструктор только один раз, но он вызывается в emplace_back, как показано в реализации stl на linux ниже. Почему это происходит?

В результате ресурс C освобождается более одного раза.

statement(statement&&) = default;             
    statement& operator=(statement&&) = default;          

    private:                   
    statement(const statement&) = delete;            
    statement& operator=(const statement&) = delete; 




396│ template<typename _Tp, typename _Alloc> 
397│  template<typename... _Args> 
398│  void 
399│  vector<_Tp, _Alloc>:: 
400│  _M_emplace_back_aux(_Args&&... __args) 
401│  { 
402│   const size_type __len = 
403│   _M_check_len(size_type(1), "vector::_M_emplace_back_aux"); 
404│   pointer __new_start(this->_M_allocate(__len)); 
405│   pointer __new_finish(__new_start); 
406│   __try 
407│   { 
408│    _Alloc_traits::construct(this->_M_impl, __new_start + size(), 
409│          std::forward<_Args>(__args)...); 
410│    __new_finish = 0; 
411│ 
412│    __new_finish 
413│    = std::__uninitialized_move_if_noexcept_a 
414│    (this->_M_impl._M_start, this->_M_impl._M_finish, 
415│    __new_start, _M_get_Tp_allocator()); 
416│ 
417│    ++__new_finish; 
418│   } 
419│   __catch(...) 
420│   { 
421│    if (!__new_finish) 
422│    _Alloc_traits::destroy(this->_M_impl, __new_start + size()); 
423│    else 
424│    std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator()); 
425│    _M_deallocate(__new_start, __len); 
426│    __throw_exception_again; 
427│   } 
428├>  std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, 
429│      _M_get_Tp_allocator()); 
430│   _M_deallocate(this->_M_impl._M_start, 
431│      this->_M_impl._M_end_of_storage 
432│      - this->_M_impl._M_start); 
433│   this->_M_impl._M_start = __new_start; 
434│   this->_M_impl._M_finish = __new_finish; 
+0

Этот ответ относится к моей проблеме: http://stackoverflow.com/a/12739939/72784 – piotr

+1

Что делать, если вы добавите какое-нибудь «noexcept» на ваш движок ctor? Это поможет? – detunized

+0

Это выглядит как функция изменения размера 'vector', т. Е. Выделяет новый буфер, копирует/перемещает элемент из старого буфера в новый буфер и уничтожает элементы в старом буфере (но не в новом буфере). Убедитесь, что конструктор перемещения правильно * передает * ресурс и оставляет перемещенный объект либо с новым ресурсом, либо без какого-либо ресурса, так что он может быть уничтожен без влияния на перемещенный объект. – dyp

ответ

4

Есть две вещей, которые избежали вашего внимания:

  1. перемещенных-от объекта еще будет подорванными, так что ваша операция перемещения должна передачи ресурсов
  2. Когда vector растет, ему может понадобиться перераспределить, который выполняет 4 шага: приобретает новое хранилище, перемещает-конструирует (или копирует-конструирует) новые элементы в новом хранилище (от старого), уничтожает старые элементы, выпускает старое хранилище.

Итак, ваша проблема заключается в том, что вы не правильно передаете ресурсы; используя std::unique_ptr в качестве основы вашего пользовательского класса, и вы не будете терпеть такие беды.

+0

Я исправил это, передав ресурс в конструкторе перемещения явно, поэтому деструктор не освобождает его в этом случае. – piotr

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