为什么在std :: move之后需要析构函数调用? [英] why is the destructor call after the std::move necessary?

查看:730
本文介绍了为什么在std :: move之后需要析构函数调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C ++编程语言第4版中,有一个矢量实现的示例,请参阅消息末尾的相关代码.

In The C++ programming language Edition 4 there is an example of a vector implementation, see relevant code at the end of the message.

uninitialized_move()通过将新的T对象从旧存储区中移出,将它们初始化到新的存储区中.然后,它将调用原始T对象(从其移出的对象)上的析构函数.为什么在这种情况下需要进行析构函数调用?

uninitialized_move() initializes new T objects into the new memory area by moving them from the old memory area. Then it calls the destructor on the original T object, the moved-from object. Why is the destructor call necessary in this case?

这是我的不完整理解:移动对象意味着将移出的对象拥有的资源的所有权转移到移入的对象.移出对象中的其余部分是某些内置类型的可能不需要删除的成员,当vector_base b超出范围时,它们将被释放(在 reserve()内部) ,在 swap()调用之后).移动对象中的所有指针都将置于nullptr或采用某种机制来删除这些资源上移动对象的所有权,以便我们安全,然后为什么在"vector_base b 交换完成后,析构函数仍会释放内存吗?

Here is my incomplete understanding: moving an object means that the ownership of the resources owned by the moved-from object are transferred to the moved-to object. The remainings in the moved-from object are some possible members of built-in types that do not need to be destroyed, they will be deallocated when the the vector_base b goes out of scope (inside reserve(), after the swap() call). All pointers in the moved-from object are to be put to nullptr or some mechanism is employed to drop ownership of moved-from object on those resources so that we are safe, then why call the destructor on a depleted object when the "vector_base b" destructor will anyway deallocate the memory after the swap is done?

我理解在必须调用析构函数的情况下有必要显式调用析构函数,因为我们有一些要解构的东西(例如drop元素),但是我在std :: move + vector_base的释放之后看不到它的含义.我在网上阅读了一些文本,然后看到从对象移出的析构函数调用是一个信号(向谁或什么?),表明该对象的生命周期已结束.

I understand the need to explicitly call the destructor in the cases when it must be called because we have something to destruct (e.g. drop elements) but I fail to see its meaning after the std::move + deallocation of vector_base. I read some texts on the net and I'm seeing the destructor call of the moved-from object as an signal (to whom or what?) that the lifetime of the object is over.

请向我说明销毁者还有哪些有意义的工作要做?谢谢!

Please clarify to me what meaningful work remains to be done by the destructor? Thank you!

下面的代码段来自此处 http://www.stroustrup.com/4th_printing3.html

The code snippet below is from here http://www.stroustrup.com/4th_printing3.html

template<typename T, typename A>
void vector<T,A>::reserve(size_type newalloc)
{
    if (newalloc<=capacity()) return;                   // never decrease allocation
    vector_base<T,A> b {vb.alloc,size(),newalloc-size()};   // get new space
    uninitialized_move(vb.elem,vb.elem+size(),b.elem);  // move elements
    swap(vb,b);                                 // install new base 
} // implicitly release old space

template<typename In, typename Out>
Out uninitialized_move(In b, In e, Out oo)
{
    using T = Value_type<Out>;      // assume suitably defined type function (_tour4.iteratortraits_, _meta.type.traits_)
    for (; b!=e; ++b,++oo) {
        new(static_cast<void*>(&*oo)) T{move(*b)};  // move construct
        b->~T();                                // destroy
    }
    return oo;       
}

推荐答案

从对象中移动只是意味着从对象移出的对象可能将其胆量捐献给另一个存在的对象[可能]要死了.但是请注意,这仅仅是因为对象捐赠了胆量,表明该对象没有死!实际上,它可能会被另一个捐赠对象复兴并依靠该对象的胆量生存.

Moving from an object just means that the moved-from object might donate its guts to live on in another live object shortly before it is [probably] going to die. Note, however, that just because an object donated its guts that the object isn't dead! In fact, it may be revived by another donating object and live on that object's guts.

另外,重要的是要了解移动结构或移动分配实际上可以是副本!实际上,如果要移动的类型恰好是具有复制构造函数或复制赋值的C ++ 11之前的类型,则它们将是复制品.即使一个类具有移动构造函数或移动分配,它也可能会选择不能将其胆量移动到新对象,例如,因为分配器不匹配.

Also, it is important to understand that move construction or move assignment can actually be copies! In fact, they will be copies if the type being moved happens to be a pre-C++11 type with a copy constructor or a copy assignment. Even if a class has a move constructor or a move assignment it may choose that it can't move its guts to the new object, e.g., because the allocators mismatch.

在任何情况下,从对象移出可能仍具有资源或需要记录统计信息或其他内容.为了摆脱对象,需要将其销毁.根据班级的合同,它甚至可能在移走后就具有定义的状态,并且可以不加任何花费地投入新的使用.

In any case, a moved from object may still have resources or need to record statistics or whatever. To get rid of the object it needs to be destroyed. Depending on the class's contracts it may even have a defined state after being moved from and could be put to new use without any further ado.

这篇关于为什么在std :: move之后需要析构函数调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆