Repository navigation
Move Semantics
Eric Brown edited this page Feb 14, 2025
·
5 revisions
- Transferring the pointer to the underlying memory instead of making a copy (memcpy)
- Situations where we do not want to copy objects around but to directly move it for better performance
- C++11 introduced rvalue references which are necessary for move semantics
- This is a faux String class to give an example of a String copy constructor
String(const String& other) {
printf("Copied");
m_Size = other.m_Size;
m_Data = new char[m_Size]; // must allocate new memory for the copy
memcpy(m_Data, other.m_data, m_Size);
}- This copy constructor is beneficial when the copy is coming from an lvalue
- However this is a waste of time and memory if it is provided an rvalue
- This is a faux String class to give an example of a String move constructor
String(String&& other) {
printf("Moved");
m_Size = other.m_Size;
m_Data = other.m_Data; // have the new m_Data instance take the pointer to the string data
// when other is deleted, it will free the heap data both the pointer both self and other.m_Data point to
// other.m_Data has to point to something else
other.m_Size = 0;
other.m_Data = nullptr;
}This wiki will go over basics of C++ lvalues and rvalues
-
lvalues are values with a name and address in memory-
lvaluereferences can only takelvalues in unless they are const
-
-
rvalues are temporary values-
rvaluereferences can only take temporaryrvalues
-
-
lvaluestypically called locator values as they have some sort of location -
Cannot take an
lvaluereference from anrvalue
int i = 10;- Think of this expression as two parts, the left and right side
- Typically, the
lvalueis on the left side of the equals sign - And typically, the
rvalueis on the right side
- Typically, the
Note: the "sides" do not always apply
- In this example
- Variable
iis thelvalue; it is a variable with a location in memory - Then
10is thervalue; it is a numeric literal with no storage or location- Until it is assigned to an
lvalue -
Cannot assign values to
rvaluesbecause it has no location
- Until it is assigned to an
- Variable
int getValue() {
return 10;
}
int main() {
int i = getValue();
}- In this case,
getValue()returns anrvalue; a temporary value- It is temporary because the returned int has no location or storage
- The
rvalueis being stored into thelvalue
// returns an lvalue reference
int& getValue() {
static int value = 10;
return value ;
}
int main() {
int i = getValue();
getValue() = i;
}-
getValue()has been modified to hold a static int- Therefore it can now be used as an
lvalue
- Therefore it can now be used as an
// returns an lvalue reference
void setValue(const int& value) {
// do something with value
}
int main() {
int i = 10;
setValue(i); // not temporary
setValue(10); // temporary
}- Cannot take an
lvaluereference from anrvalue- if
setValue(int& value)params takes a reference to anlvalue, it cannot therefore take anrvalue, i.e. 10
- if
- If it is a
const lvaluereference, it can be assigned anrvalue:
int i = 10;
int& a = 10; // THIS DOES NOT WORK
cosnt int& a = 10; // THIS WORKSC++17 updated the lvalue and rvalue to have more specific categories

-
glvalue("generalized" lvalue): is an expression whose evaluation determines the identity of an object or function -
prvalue("pure" rvalue): is an expression whose evaluation- computes the value of an operand of a built-in operator (such prvalue has no result object)
- initializes an object (such prvalue has a result object)
-
xvalue("eXpiring" value): aglvaluethat denotes an object whose resources can be reused -
lvalue: aglvaluethat is not anrvalue -
rvalue: aprvalueorxvalue-prvalues