为什么emplace_back调用析构函数?

pio*_*otr 10 c++ vector move-semantics c++11

我有一个删除了复制ctor的类和一个释放C资源的析构函数.

我希望emplace_back能够移动对象并只调用析构函数一次,但是它会在emplace_back中调用,如下面linux上的stl实现中所示.为什么会这样?

结果是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;
Run Code Online (Sandbox Code Playgroud)

Mat*_* M. 8

有两件事情没有引起你的注意:

  1. 移动的对象仍将被销毁,因此您的移动操作必须传输资源
  2. 当a vector增长时,可能需要重新分配哪个是4步操作:获取新存储,在新存储中移动构造(或复制构造)新元素(从旧存储),销毁旧元素,释放旧存储.

所以,你的问题只是你没有正确地转移资源; 使用std::unique_ptr作为您的自定义类的基础,你不会遭受这样的困境.