Are moved-from objects required to be destructed?

谁都会走 提交于 2019-12-01 14:35:55

问题


If I move-construct a from b, is it still necessary to destruct b, or can I get away without doing so?

This question crossed my mind during the implementation of an optional<T> template. Excerpt:

~optional()
{
    if (initialized)
    {
        reinterpret_cast<T*>(data)->~T();
    }
}

optional(optional&& o) : initialized(o.initialized)
{
    if (initialized)
    {
        new(data) T(std::move(*o));   // move from o.data
        o.initialized = false;        // o.data won't be destructed anymore!
    }
}

Of course, I could just replace the bool initialized with a three-valued enumeration that distinguishes between initialized, non-initialized and moved-from. I just want to know if this is strictly necessary.


回答1:


Yes, it is still necessary to destruct b. A moved from object is a valid, constructed object. In some cases, it may even hold resources that still need to be disposed of. In generic code such as you show, T may not even have a move constructor. You may invoke a copy constructor instead in this case. So you can definitely not assume that ~T() is a no-op and can be elided.




回答2:


Yes, you do still have to destruct them. One of the designs that can show this flaw is for example, observer-based patterns where one object keeps lists of pointers to another. Not running the destructor won't remove the pointer and the code will crash when it attempts to access an object that no longer exists.

The easier thing to do in your example is just to not set initialized to false in the moved-from object. The value is still defined to be in a valid state after being moved from, and the destructor of the rvalue you're referring to would clean it up with no further intervention.




回答3:


I'd like to answer 'No' to your question but I'm not sure it's even the right question to ask. Consider the following:

{  // start of scope
    T maybe_moved;
    if(some_condition) {
        T(std::move(maybe_moved));
    }
// end of scope
}

T::~T() should obviously be called only once for the maybe_moved object. If a move constructor would call it, how would you make such innocuous code work?



来源:https://stackoverflow.com/questions/6943805/are-moved-from-objects-required-to-be-destructed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!