开发者

Are moved-from objects required to be destructed?

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-initialize开发者_JAVA百科d and moved-from. I just want to know if this is strictly necessary.


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.


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.


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?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜