-1
A a5(move(a1));

While after the move the member vars of a1 are set to defaults, a1 itself is not set to null. You can't do a1 == nullptr... to check if a1 is useless...

I find this odd. Is there something I'm misunderstanding here? I would think that if a1 is moved, it becomes useless, this should be indicated by setting it to null somehow. No?

The thing is that by leaving a1 in a non null state, it still can be used. There is no compiler warning or error. There is no real indication that the object is in a messed up state. if a has two member vars, an int and a dynamically alloc object, the dyn alloc object will point to nullptr but the int will have a def value (of course only if implemented right...easy to mess up).

So after the move you can

int number = a1.getInt();

and get back a number not realizing that a1 has been reset. In C and C++ we're taught to set pointers to null (a.k.a nullptr or NULL) when its resource is pilfered to eliminate such confusion. With the introduction of moving which pilfers resources of an object, is there no built in mechanism or best practice to indicate the object has been pilfered and thus left "reset" to default construction state?

EDIT Added sample move c'tor

A(A&& other) : num(other.num), s(other.s){
   other.num = 0;
   other.s = nullptr;     //dyn alloc obj
}
code
  • 1,056
  • 10
  • 22
  • 2
    C++ doesn't have a generalized way to set an object to "null" like other languages. Typically `move`ing an object will either copy or leave it in an "empty" state but thats entirely up to the implementation – kmdreko Feb 27 '18 at 00:07
  • "Null" isn't a general thing in C++. – Kerrek SB Feb 27 '18 at 00:11
  • The requirement of a move operation is to leave the object in a valid but unspecified state that may be safely destructed. There is no requirement that it leave the object in an "empty" or "null" state. – Peter Feb 27 '18 at 00:16
  • So is there no way to know or check if an object has been pilfered? – code Feb 27 '18 at 00:35

2 Answers2

1

Why doesn't moving an object leave it null?

Because if the object is not a pointer, then it does not, in general, have a "null state", so you can't "leave it null"; and if it is a pointer you don't make it null when you "move" from it.

Leaving a1 in a non null state, it still can be used. There is no compiler warning or error. There is no real indication that the object is in a messed up state...

It's not in a messed-up state, it's in a valid state. But perhaps it's not a bad idea for there to be warning when you use the post-move value of a moved-from object.

einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • I also think it is a good idea to have some warning or some check. But apparently either people don't understand the question or don't think it is a good idea considering the down vote. Don't you just love it when people down vote without any explanation? – code Feb 27 '18 at 01:02
  • @code: There is a terrible downvote culture on StackOverflow, in my opinion. People downvote you for all sorts of irrelevant reasons - instead of flagging; because you've misunderstood something (which is what asking is all about); and so on. Also, see [this](https://meta.stackexchange.com/questions/307414/dont-comment-on-your-downvote-just-the-opposite/). – einpoklum Feb 27 '18 at 18:01
  • Having said that - your question is kind of poorly phrased - you don't explain where A and a1 come from etc. – einpoklum Feb 27 '18 at 18:10
0

The result of a move operation is supposed to leave the object in a valid but unspecified state. Typically you would move if you are going to destroy the object, or assign new values to the object. You would not normally attempt to use an object after moving out of it.

The move-constructor for a1's type is responsible for performing the move and leaving the object in the state that you wish. If the default-generated move constructor does not behave as you would like then you can write your own move constructor for the object. For example you could set a pointer to null in this move constructor. Or you could set a flag which indicates the object is in a moved-from state.

In your question the behaviour you "wish for" is more like the behaviour of swapping with an empty object. Perhaps the following code would suit you better:

A a5{};
using std::swap;
swap(a5, a1);

Regarding the update which suggests other.s points to a "dyn alloc obj": you should avoid doing this because it means you have to waste time writing a copy-constructor, move-constructor, copy-assignment operator, move-assignment operator, and destructor.

You are the architect of your own demise here: by introducing this pointer to your class you create the exact problem with moving that you are complaining about.

Instead any owned resource should be managed by its own class. The standard library's std::unique_ptr suffices for many such use cases.

M.M
  • 138,810
  • 21
  • 208
  • 365
  • Thanks, while I agree with what you state here, and I already knew this. respectfully, this is not what I was asking. I was asking if there is a way to know or check if an object has been pilfered? – code Feb 27 '18 at 01:06
  • @code your question title is "Why doesn't moving an object leave it null?", not "How do I know if an object has been moved from?". I bolded the part of my answer that covers this other question. – M.M Feb 27 '18 at 01:10
  • Thanks M.M. Perhaps the title isn't ideal but the entire question if you read it is about potential miss use post move operation due to not being able to identify pilfered objects. – code Feb 27 '18 at 01:20
  • @code yes, I address that in my answer and explain what you should do – M.M Feb 27 '18 at 01:31