Move semantics is a feature, introduce in C++11, to allow the optimization of copying object, where the value is no longer needed.
This is particularly beneficial for objects that manage resources such as memory, file handles, or network connections.
To support move semantics a new type of reference has been introduced: the rvalue refernce. It refers only to two types of object:
- Temporary objects without a name
- Object marked with
std::move
Example:
std::string returnBest90sBand(){
return "Red Hot Chili Peppers";
}
//...
std::string best70sBand{"PinkFloyd"}
// 1 temporary objects without name
std::string&& band{returnBest90sBand()};
std::string&& band2{best70sBand};
// std::string&& notValidInitialization{best70sBand}; best70sBand is not a rvalue
// 2 Object marked as std::move
std::string&& band3{std::move(best70sBand)};
Obsareve that rvalue references are declared with &&
and no const
std::move
and moved-form objects
std::move
is a static_cast
to a rvalue reference: static_cas<decltype(obj)&&>(obj)
. The following delcaration are equal:
foo(std::string && s);
foo(static_cas<std::string&&>(s));
Object marked with std::move
After a std::move
, the object is in a moved-form. This means that it still a valid, but you do not know its value. It is like function parameter where you do not its value. The standard library call this behaviour valid but unspecified state.
Example:
std::string artist{"daftPunk"};
foo(std::move(artist));
std::cout<<s<<std::endl; // ok but unknow value
std::cout<<s.size()<<std::endl; // ok
std::cout<<s.front()<<std::endl; // error, potentially undefined behavior
artist="PinkFloyd"; // ok, reusing moved-form object is permitted
Move Semantics Guidelines
- Avoid Object with Names
- Avoid unecessary
std::move
: from C++11 return value optimization (RVO) is implemented. - Initialize class members with move semantics: for better performance
References
- C++ Move Semantics. Nicolai Josuttis