【发布时间】:2014-03-05 23:04:20
【问题描述】:
我有一个带有已删除复制 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;
【问题讨论】:
-
这个答案和我的问题有关:stackoverflow.com/a/12739939/72784
-
如果您在移动 ctor 上添加一些
noexcept会怎样?这会有帮助吗? -
这看起来像
vector的调整大小函数,即它分配一个新缓冲区,将元素从旧缓冲区复制/移动到新缓冲区,并销毁旧缓冲区中的元素(但不在新缓冲区中)。确保您的移动构造函数正确地转移资源并将被移动的对象留下新资源或不带任何资源,这样它就可以在不影响移动到的对象的情况下被销毁. -
@detunized
vector仅当移动 ctor 不是 noexcept 并且 可以使用复制 ctor(如果类型为CopyInsertable)时才会复制。对于statement类型,复制ctor 是私有的,因此将使用移动ctor(具有较弱的异常安全保证)。 -
@detunized 移动 ctor 是默认值,这意味着它是 noexcept。此外,通过 STL 的代码路径表明正在移动对象。移动 ctor 已删除。
标签: c++ c++11 vector move-semantics