Question

I am new to c++11 and wrote the following code to understand how std::move works:

#include <queue>
#include <stdio.h>

class X {
 public:
  X(int x) : x_(x) {}
  ~X() {
    printf("X(%d) has be released.\n", x_);
  }

  X(X&&) = default;
  X& operator = (X&&) = default;

  X(const X&) = delete;
  X& operator = (const X&) = delete;
 private:
  int x_;
};


int main() {
  std::queue<X> xqueue;
  for (int x = 0; x < 5; ++x) {
    xqueue.push(std::move(X(x)));
  }
  return 0;
}

However, it generates the following output, which indicates that the destructor of each X(n) has been called twice:

X(0) has be released.
X(1) has be released.
X(2) has be released.
X(3) has be released.
X(4) has be released.
X(0) has be released.
X(1) has be released.
X(2) has be released.
X(3) has be released.
X(4) has be released.

I can imagine the second round of the output happens right at the end of main() function, and the first round probably happens in the loop when those intermediate Xs ran out of scope.

But, I thought the ownership of such intermediate Xs will be perfectly transferred into the queue and their destructors should not be called during their ownership transfer.

So my questions are:

  1. When I saw an instance being deallocated twice, does that mean it performs copy instead of move?
  2. If the above answer is yes, then how can I really avoid copying?

Thank you,

Était-ce utile?

La solution

If you move from one object to another object, you still have two objects in total. They both need to be destroyed. Perhaps move is a slightly misleading term, but it is not the object itself that is moved from one place to another (objects never actually move) - it's the contents of the object.

  1. No. As stated above, a move does not disappear away one of the objects. Both a copy and move from one object to another will have two objects involved. The difference is what effect they have on the objects. A copy will of course copy the members of one object to the other. A move, on the other hand, will move the members from one object to another - typically a faster operation.
  2. N/A

Autres conseils

The move constructor steals attributes/members of an object and gives it to the new object. So in your example, the first set of delete statements occurs when the scope of the move constructor ends and the now empty object is destroyed.

And the second set of delete statements occur when the newly created objects inside the queue are destroyed

Also it is worth noting that if the attributes of the deleted object are not POD types, then it is not a good idea to access them in the delete method otherwise that would cause a seg fault

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top