Rvalue references allow a function to branch at compile time (via
overload resolution) on the condition "Am I being called on an lvalue or
an rvalue?" It is true that you can overload any function in this manner,
as shown above. But in the overwhelming majority of cases,this kind of overload should occur only for copy constructorsand assignment operators, for the purpose of achieving movesemantics.
How to understand move semantics? Move is not really move a big chunk of
data, It just move index of data. just like you move file in the hard
disk.
rvalues denote temporaries or objects that want to look like a temporary.
What is so particular about temporaries, is the fact that they will be used in
a very limited way: their value will be read once, and they will be destroyed.
This is a very useful observation in implementing "move semantics." In
other words, "steal resource"
Typical, if you class allocate a lot of allocated resource (new, orvector, or sth else). You should implement two copy ctor A few
explanations are below:
Not move copy ctor will steal resource automatically, you need to
coding it by your self.
You can’t steal in normal ctor. because, It must keep origin obj
intact. You can steal when Foo(f1+f2), but when you used Foo(f1).
It will destory f1.
Without move copy ctor, normal copy ctor will treat Foo(f1+f2)
and Foo(f1) the same way.
With move copy ctor, normal copy ctor deal with Foo(f1), and
move deal with Foo(f1+f2), for f1+f2, you can steal resource,
because nobody need to use f1+f2 later any more.
In previous examples Foo obj1=obj2+obj3. if you don’t have move ctor, In
operator + function, a temp objtemp1 is produced, and when operator+
function return, another temp objtemp2 is produced . Then in the end,
objtemp2 is passed to ctor, . So, ctor is called three times. and copy content
is also called three times.
If you have move ctor. In operator + function, a temp objtemp1 is
produced, When return objtemp1, It will not produce objtemp2. (becasue
objtemp1 is rvalue.) then objtemp1 is passed to move ctor. In side move
ctor, the resource address has been move to new obj1. Just one temp
objtemp1 and one actual copy happen. ( just new pointer = old pointer; and
old pointer = NULL).
Move ctor and move assignment work with rvalue, What if you want to use
them with lvalues? You can call std::move function, It will call you
move ctor or assignment to "move" resource, not "copy" resource.