繁体   English   中英

为什么emplace_back调用析构函数?

[英]Why is emplace_back calling destructor?

我有一个删除了副本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;

有两件事逃避了您的注意:

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

因此,您的问题很简单,就是您没有正确传输资源。 使用std::unique_ptr作为自定义类的基础,您将不会遭受此类麻烦。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM