0

The following is a snippet right at the end of this article by Mr. Thomas Becker:

X& X::operator=(X&& rhs)
{

  // Perform a cleanup that takes care of at least those parts of the
  // destructor that have side effects. Be sure to leave the object
  // in a destructible and **assignable state**.

  // Move semantics: exchange content between this and rhs

  return *this;
}

What does the author mean by "leave the object in an assignable state" above?

Ayrosa
  • 3,385
  • 1
  • 18
  • 29
  • related: https://stackoverflow.com/questions/12095048/what-constitutes-a-valid-state-for-a-moved-from-object-in-c11 – NathanOliver Jul 29 '19 at 18:29
  • In short, assigning to the object should not cause undefined behavior, and the object should assume the assigned value. i.e. `something = std::move(object); object = X(...);` should be valid and do the expected thing. – Justin Jul 29 '19 at 18:33
  • @NathanOliver Thanks for the link. It seems to answer my question. – Ayrosa Jul 29 '19 at 18:34
  • @Ayrosa OK. I've closed it as a dupe – NathanOliver Jul 29 '19 at 18:35
  • @Ayrosa An example: suppose you have a class with the invariant that the `Data* data` member is not null. In your assignment operator, you write `*data = *rhs.data;`, which is safe because `data` is not null. However, if in your move assignment operator, you the proceeded to write `rhs.data = nullptr;`, you have set `rhs` to a non-assignable state, because `rhs = /* some value */` will dereference the null pointer. – Justin Jul 29 '19 at 18:38
  • @Justin I'm assuming that when the author says "leave the object in a destructible state", he means `Data* data = nullptr;`. Then, according to your comment above you can't have both (destructible and assignable state), which is exactly the opposite of what the author is saying. – Ayrosa Jul 29 '19 at 18:46
  • @Ayrosa No, you can have both. Some examples on how to do so: instead of `rhs.data = nullptr;`, you could write `rhs.data = new Data;`. Instead of `*data = *rhs.data;`, you could write `if (data && rhs.data) *data = *rhs.data;` and forgo the invariant. There are other viable options as well. – Justin Jul 29 '19 at 19:11

0 Answers0