This browser is no longer supported.

Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.

Move Constructors and Move Assignment Operators (C++)

  • 9 contributors

This topic describes how to write a move constructor and a move assignment operator for a C++ class. A move constructor enables the resources owned by an rvalue object to be moved into an lvalue without copying. For more information about move semantics, see Rvalue Reference Declarator: && .

This topic builds upon the following C++ class, MemoryBlock , which manages a memory buffer.

The following procedures describe how to write a move constructor and a move assignment operator for the example C++ class.

To create a move constructor for a C++ class

Define an empty constructor method that takes an rvalue reference to the class type as its parameter, as demonstrated in the following example:

In the move constructor, assign the class data members from the source object to the object that is being constructed:

Assign the data members of the source object to default values. This prevents the destructor from freeing resources (such as memory) multiple times:

To create a move assignment operator for a C++ class

Define an empty assignment operator that takes an rvalue reference to the class type as its parameter and returns a reference to the class type, as demonstrated in the following example:

In the move assignment operator, add a conditional statement that performs no operation if you try to assign the object to itself.

In the conditional statement, free any resources (such as memory) from the object that is being assigned to.

The following example frees the _data member from the object that is being assigned to:

Follow steps 2 and 3 in the first procedure to transfer the data members from the source object to the object that is being constructed:

Return a reference to the current object, as shown in the following example:

Example: Complete move constructor and assignment operator

The following example shows the complete move constructor and move assignment operator for the MemoryBlock class:

Example Use move semantics to improve performance

The following example shows how move semantics can improve the performance of your applications. The example adds two elements to a vector object and then inserts a new element between the two existing elements. The vector class uses move semantics to perform the insertion operation efficiently by moving the elements of the vector instead of copying them.

This example produces the following output:

Before Visual Studio 2010, this example produced the following output:

The version of this example that uses move semantics is more efficient than the version that does not use move semantics because it performs fewer copy, memory allocation, and memory deallocation operations.

Robust Programming

To prevent resource leaks, always free resources (such as memory, file handles, and sockets) in the move assignment operator.

To prevent the unrecoverable destruction of resources, properly handle self-assignment in the move assignment operator.

If you provide both a move constructor and a move assignment operator for your class, you can eliminate redundant code by writing the move constructor to call the move assignment operator. The following example shows a revised version of the move constructor that calls the move assignment operator:

The std::move function converts the lvalue other to an rvalue.

Rvalue Reference Declarator: && std::move

Was this page helpful?

Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see: https://aka.ms/ContentUserFeedback .

Submit and view feedback for

Additional resources

move assignment or constructor

C++11 Tutorial: Introducing the Move Constructor and the Move Assignment Operator

Copy constructors sounds like a topic for an article from 1989. And yet, the changes in the new C++ standard affect the design of a class' special member functions fundamentally. Find out more about the impact of move semantics on objects' behavior and learn how to implement the move constructor and the move assignment operator in C++11.

C++11 is the informal name for ISO/IEC 14882:2011, the new C++ standard that was published in September 2011. It includes the TR1 libraries and a large number of new core features (a detailed discussion about these new C++11 features is available here ; also see The Biggest Changes in C++11 (and Why You Should Care) ):

  • Initializer lists
  • Uniform initialization notation
  • Lambda functions and expressions
  • Strongly-typed enumerations
  • Automatic type deduction in declarations
  • __thread_local storage class
  • Control and query of object alignment
  • Static assertions
  • Type long long
  • Variadic templates

Important as these features may be, the defining feature of C++11 is rvalue references .

The Right Time for Rvalue References

Rvalue references are a new category of reference variables that can bind to rvalues .  Rvalues are slippery entities, such as temporaries and literal values; up until now, you haven't been able to bind these safely to reference variables.

Technically, an rvalue is an unnamed value that exists only during the evaluation of an expression. For example, the following expression produces an rvalue:

x+(y*z); // A C++ expression that produces a temporary 

C++ creates a temporary (an rvalue) that stores the result of y*z , and then adds it to x . Conceptually, this rvalue evaporates by the time you reach the semicolon at the end of the full expression.

A declaration of an rvalue reference looks like this:

std::string&& rrstr; //C++11 rvalue reference variable

The traditional reference variables of C++ e.g.,

std::string& ref;

are now called lvalue references .

Rvalue references occur almost anywhere, even if you don't use them directly in your code. They affect the semantics and lifetime of objects in C++11. To see how exactly, it's time to talk about move semantics .

Get to Know Move Semantics

Hitherto, copying has been the only means for transferring a state from one object to another (an object's state is the collective set of its non-static data members' values). Formally, copying causes a target object t to end up with the same state as the source s , without modifying s . For example, when you copy a string s1 to s2 , the result is two identical strings with the same state as s1 .

And yet, in many real-world scenarios, you don't copy objects but move them. When my landlord cashes my rent check, he moves money from my account into his. Similarly, removing the SIM card from your mobile phone and installing it in another mobile is a move operation, and so are cutting-and-pasting icons on your desktop, or borrowing a book from a library.

Notwithstanding the conceptual difference between copying and moving, there's a practical difference too: Move operations tend to be faster than copying because they transfer an existing resource to a new destination, whereas copying requires the creation of a new resource from scratch. The efficiency of moving can be witnessed among the rest in functions that return objects by value. Consider:

string func()

//do something with s

string mystr=func();

When func() returns, C++ constructs a temporary copy of s on the caller's stack memory. Next, s is destroyed and the temporary is used for copy-constructing mystr . After that, the temporary itself is destroyed. Moving achieves the same effect without so many copies and destructor calls along the way.

Moving a string is almost free; it merely assigns the values of the source's data members to the corresponding data members of the target. In contrast, copying a string requires the allocation of dynamic memory and copying the characters from the source.

Move Special Member Functions

C++11 introduces two new special member functions: the move constructor and the move assignment operator . They are an addition to the fabulous four you know so well:

  • Default constructor
  • Copy constructor
  • Copy assignment operator

If a class doesn't have any user-declared special member functions (save a default constructor), C++ declares its remaining five (or six) special member functions implicitly, including a move constructor and a move assignment operator. For example, the following class

doesn't have any user-declared special member functions. Therefore, C++ declares all of its six special member functions implicitly. Under certain conditions , implicitly declared special member functions become implicitly defined as well. The implicitly-defined move special member functions move their sub-objects and data members in a member-wise fashion. Thus, a move constructor invokes its sub-objects' move constructors, recursively. Similarly, a move assignment operator invokes its sub-objects' move assignment operators, recursively.

What happens to a moved-from object? The state of a moved-from object is unspecified. Therefore, always assume that a moved-from object no longer owns any resources, and that its state is similar to that of an empty (as if default-constructed) object. For example, if you move a string s1 to s2 , after the move operation the state of s2 is identical to that of s1 before the move, whereas s1 is now an empty (though valid) string object.

Designing a Move Constructor

A move constructor looks like this:

C::C(C&& other); //C++11 move constructor

It doesn't allocate new resources. Instead, it pilfers other 's resources and then sets other to its default-constructed state.

Let's look at a concrete example. Suppose you're designing a MemoryPage class that represents a memory buffer:

class MemoryPage

size_t size;

char * buf;

explicit MemoryPage(int sz=512):

size(sz), buf(new char [size]) {}

~MemoryPage( delete[] buf;}

//typical C++03 copy ctor and assignment operator

MemoryPage(const MemoryPage&);

MemoryPage& operator=(const MemoryPage&);

A typical move constructor definition would look like this:

MemoryPage(MemoryPage&& other): size(0), buf(nullptr)

// pilfer other's resource

size=other.size;

buf=other.buf;

// reset other

other.size=0;

other.buf=nullptr;

The move constructor is much faster than a copy constructor because it doesn't allocate memory nor does it copy memory buffers.

Designing a Move Assignment Operator

A move assignment operator has the following signature:

C& C::operator=(C&& other);//C++11 move assignment operator

A move assignment operator is similar to a copy constructor except that before pilfering the source object, it releases any resources that its object may own. The move assignment operator performs four logical steps:

  • Release any resources that *this currently owns.
  • Pilfer other 's resource.
  • Set other to a default state.
  • Return *this .

Here's a definition of MemoryPage 's move assignment operator:

MemoryPage& MemoryPage::operator=(MemoryPage&& other)

if (this!=&other)

// release the current object's resources

delete[] buf;

return *this;

Overloading Functions

The overload resolution rules of C++11 were modified to support rvalue references. Standard Library functions such as vector::push_back() now define two overloaded versions: one that takes const T& for lvalue arguments as before, and a new one that takes a parameter of type T&& for rvalue arguments. The following program populates a vector with MemoryPage objects using two push_back () calls:

#include <vector>

using namespace std;

vector<MemoryPage> vm;

vm.push_back(MemoryPage(1024));

vm.push_back(MemoryPage(2048));

Both push_back() calls resolve as push_back(T&&) because their arguments are rvalues. push_back(T&&) moves the resources from the argument into vector 's internal MemoryPage objects using MemoryPage 's move constructor. In older versions of C++, the same program would generate copies of the argument since the copy constructor of MemoryPage would be called instead.

As I said earlier, push_back(const T&) is called when the argument is an lvalue:

MemoryPage mp1(1024);//lvalue

vm.push_back(mp); //push_back(const T&)

However, you can enforce the selection of push_back(T&&) even in this case by casting an lvalue to an rvalue reference using static_cast :

//calls push_back(T&&)

vm.push_back(static_cast<MemoryPage&&>(mp));

Alternatively, use the new standard function std::move() for the same purpose:

vm.push_back(std::move(mp));//calls push_back(T&&)

It may seem as if push_back(T&&) is always the best choice because it eliminates unnecessary copies. However, remember that push_back(T&&) empties its argument. If you want the argument to retain its state after a push_back() call, stick to copy semantics. Generally speaking, don't rush to throw away the copy constructor and the copy assignment operator. In some cases, the same class could be used in a context that requires pure copy semantics, whereas in other contexts move semantics would be preferable.

In Conclusion

C++11 is a different and better C++. Its rvalue references and move-oriented Standard Library eliminate many unnecessary copy operations, thereby improving performance significantly, with minimal, if any, code changes. The move constructor and the move assignment operator are the vehicles of move operations. It takes a while to internalize the principles of move semantics – and to design classes accordingly. However, the benefits are substantial. I would dare predicting that other programming languages will soon find ways to usher-in move semantics too.

Danny Kalev is a certified system analyst by the Israeli Chamber of System Analysts and software engineer specializing in C++. Kalev has written several C++ textbooks and contributes C++ content regularly on various software developers' sites. He was a member of the C++ standards committee and has a master's degree in general linguistics.

  • The Biggest Changes in C++11 (and Why You Should Care)
  • C11: A New C Standard Aiming at Safer Programming

move assignment or constructor

Additional Links

  • Analysis of Algorithms
  • Backtracking
  • Dynamic Programming
  • Divide and Conquer
  • Geometric Algorithms
  • Mathematical Algorithms
  • Pattern Searching
  • Bitwise Algorithms
  • Branch & Bound
  • Randomized Algorithms
  • Java Equivalent of C++'s lower_bound() Method
  • Overloads of the Different References in C++
  • How to copy elements of an Array in a Vector in C++
  • std::plus in c++
  • Descending Order in Map and Multimap of C++ STL
  • Class template with multiple parameters
  • is_final template in C++14
  • Erase-Remove Idiom in C++
  • Vector of Unordered Maps in C++ with Examples
  • is_volatile template in C++
  • std::divides in C++
  • is_standard_layout template in C++
  • std::minmax() and std::minmax_element() in C++ STL
  • Find and print duplicate words in std::vector<string> using STL functions
  • is_empty template in C++
  • reduce in C++ STL
  • Map of Vectors in C++ STL with Examples
  • The C++ Standard Template Library (STL)
  • Range-based for loop in C++

std::move in Utility in C++ | Move Semantics, Move Constructors and Move Assignment Operators

Prerequisites:

  • lvalue reference
  • rvalue reference
  • Copy Semantics (Copy Constructor)

References:

In C++ there are two types of references-

  • An lvalue is an expression that will appear on the left-hand side or on the right-hand side of an assignment.
  • Simply, a variable or object that has a name and memory address.
  • It uses one ampersand (&).
  • An rvalue is an expression that will appear only on the right-hand side of an assignment.
  • A variable or object has only a memory address (temporary objects).
  • It uses two ampersands (&&).

Move Constructor And Semantics:

The move constructor was introduced in C++11 . The need or purpose of a move constructor is to steal or move as many resources as it can from the source (original) object , as fast as possible, because the source does not need to have a meaningful value anymore, and/or because it is going to be destroyed in a moment anyway. So that one can avoid unnecessarily creating copies of an object and make efficient use of the resources

While one can steal the resources, but one must leave the source (original) object in a valid state where it can be correctly destroyed.

Move constructors typically “steal” the resource of the source (original) object rather than making several copies of them, and leaves the source object in a “valid but unspecified state”.

The copy constructor uses the lvalue references which are marked with one ampersand (&) while the move constructor uses the rvalue references are marked with two ampersands (&&).

std::move() is a function used to convert an lvalue reference into the rvalue reference. Used to move the resources from a source object i.e. for efficient transfer of resources from one object to another. std::move() is defined in the <utility> header .
template< class T >  typename std::remove_reference<T>::type&& move(T&& t) noexcept;                 (since C++11)(until C++14) template< class T >  constexpr std::remove_reference_t<T>&& move(T&& t) noexcept                       (since C++14)

Example: Below is the C++ program to show what happens without using move semantics i.e. before C++11.

Explanation:

Assuming the program is compiled and executed using a compiler that doesn’t support move semantics. In the main() function,  

1. std::vector<std::string> vecString;- An empty vector is created with no elements in it.  2. vecString = createAndInsert();- The createAndInsert() function is called. 3. In createAndInsert() function-

  • std::vector<std::string> vec;- Another new empty vector named as vec is created.
  • vec.reserve(3);- Reserving the size of 3 elements.
  • std::string str(“Hello”);- A string named as str initialized with a “Hello”.
  • vec.push_back( str );- A string is passed by value into the vector vec. Therefore a (deep) copy of str will be created and inserted into the vec by calling a copy constructor of the String class.
  • A temporary object will be created (str + str) with its own separate memory.
  • This temporary object is inserted into vector vec which is passed by value again means that a (deep) copy of the temporary string object will be created.
  • As of now, the temporary object is no longer needed hence it will be destroyed.

Note: Here, we unnecessarily allocate & deallocate the memory of the temporary string object. which can be optimized (improved) further just by moving the data from the source object. 

  • vec.push_back( str );- The same process as of Line no. 5 will be carried out. Remember at this point the str string object will be last used.
  • Firstly, the string object str will be destroyed because the scope is left where it is declared.
  • Secondly, a local vector of string i.e vec is returned. As the return type of the function is not by a reference. Hence, a deep copy of the whole vector will be created by allocating at a separate memory location and then destroys the local vec object because the scope is left where it is declared.
  • Finally, the copy of the vector of strings will be returned to the caller main() function.
  • At the last, after returning to the caller main() function, simply printing the elements of the local vecString vector.

Example: Below is the C++ program to implement the above concept using move semantics i.e. since C++11 and later. 

Here, in order to use the move semantics. The compiler must support the C++11 standards or above. The story of execution for the main() function and createAndInsert() function remains the same till the line vec.push_back( str );

A question may arise why the temporary object is not moved to vector vec using std::move(). The reason behind it is the push_back() method of the vector. Since C++11 the push_back() method has been provided with its new overloaded version.

Syntax:  

constexpr void push_back(const T& value);                                        (since C++20) void push_back(T&& value);                                                              (since C++11) (until C++20) void push_back(const T& value);                                                        (until C++20) constexpr void push_back(T&& value);                                              (since C++20)
  • A temporary object will be created (str + str) with its own separate memory and will make a call to overloaded push_back() method (version 2nd  or 4th depends on the version of C++) which will steal (or moved) the data from the temporary source object (str + str) to the vector vec as it is no longer required.
  • After performing the move the temporary object gets destroyed. Thus rather than calling the copy constructor (copy semantics), it is optimized just by copying the size of the string and manipulating pointers to the memory of the data.
  • Here, the important point to note is that we make use of the memory which will soon no longer owns its memory. In another word, we somehow optimized it. That’s all because of the rvalue reference and move semantics.
  • vec.push_back(std::move(str));- Here the compiler is explicitly hinted that “object is no longer needed” named as str ( lvalue reference ) with the help of std::move() function by converting the lvalue reference into rvalue reference and the resource of the str will be moved to the vector. Then the state of str becomes a “valid but unspecified state”. This doesn’t matter to us because for the last time we are going to use and soon be destroyed in a moment anyway.
  • Lastly, return the local vector of string called vec to its caller.
  • In the end, returned to the caller main() function, and simply printing the elements of the local vecString vector.

A question may arise while returning the vec object to its caller. As it is not required anymore and also a whole temporary object of a vector is going to be created and also local vector vec will be destroyed, then why std::move() is not used to steal the value and return it.  Its answer is simple and obvious, there is optimization at the compiler level known as (Named) Return Value Object, more popularly known as RVO . 

Some Fallback Of Move Semantics:  

  • It doesn’t make any sense to steal or move the resources of a const object.
  • See constObjectCallFunc() function in the below program
  • See baz() function in the below program
  • See bar() function in the below program

Note: The foo() function have all necessary types of arguments.

Below is the C++ program to implement all the above concepts- 

Summary:  

  • Move semantics allows us to optimize the copying of objects, where we do not need the worth. It is often used implicitly (for unnamed temporary objects or local return values) or explicitly with std::move().
  • std::move() means “no longer need this value” .
  • An object marked with std::move() is never partially destroyed. i.e. The destructor will be called to destroy the object properly.

Please Login to comment...

Similar reads.

  • Blogathon-2021
  • Constructors
  • C++ Programs
  • Competitive Programming
  • How to Use ChatGPT with Bing for Free?
  • 7 Best Movavi Video Editor Alternatives in 2024
  • How to Edit Comment on Instagram
  • 10 Best AI Grammar Checkers and Rewording Tools
  • 30 OOPs Interview Questions and Answers (2024)

Improve your Coding Skills with Practice

 alt=

What kind of Experience do you want to share?

Lets Understand With Example

Move constructor and Move assignment c++11

Move operation.

Operation that is being used to move (steal) the value from source object to destination object and leaving source object in valid state and unspecified state.

Move Semantics

These are two operations (Move constructor and Move assignment) that are used to move the value of object instead of copy. These will be provided by compiler by default like copy constructor, assign operator, default constructor and destructor, if we don’t define by our-self.

Move Constructor

It is constructor that mean we are creating new object and getting(stealing) value from object and leaving that object in valid state and unspecified state. It will be provided by compiler by default, we can define it like below and it will NOT be overwritten by compiler.

Move Assignment Operator

It is operator to assign the new value to existing object and getting (stealing) new value from object and leaving that object in valid state and unspecified state. It will be provided by compiler by default, we can define it like below and it will NOT be overwritten by compiler.

Source code with example using default move semantics:

Source code with example using user defined move semantics:.

cppreference.com

Search

Move constructors

A move constructor of class T is a non-template constructor whose first parameter is T && , const T && , volatile T && , or const volatile T && , and either there are no other parameters, or the rest of the parameters all have default values. A type with a public move constructor is MoveConstructible .

[ edit ] Syntax

[ edit ] explanation.

  • Typical declaration of a move constructor
  • Forcing a move constructor to be generated by the compiler
  • Avoiding implicit move constructor

The move constructor is called whenever an object is initialized from xvalue of the same type, which includes

  • initialization, T a = std:: move ( b ) ; or T a ( std:: move ( b ) ) ; , where b is of type T
  • function argument passing: f ( std:: move ( a ) ) ; , where a is of type T and f is void f ( T t )
  • function return: return a ; inside a function such as T f ( ) , where a is of type T which has a move constructor.

Move constructors typically "steal" the resources held by the argument (e.g. pointers to dynamically-allocated objects, file descriptors, TCP sockets, I/O streams, running threads, etc), rather than make copies of them, and leave the argument in some valid but otherwise indeterminate state. For example, moving from a std:: string or from a std:: vector turns the argument empty.

[ edit ] Implicitly-declared move constructor

If no user-defined move constructors are provided for a class type ( struct , class , or union ), and all of the following is true:

  • there are no user-declared copy constructors
  • there are no user-declared copy assignment operators
  • there are no user-declared move assignment operators
  • there are no user-declared destructurs
  • the implicitly-declared move constructor would not be defined as deleted

then the compiler will declare a move constructor as an inline public member of its class with the signature T::T(T&&)

A class can have multiple move constructors, e.g. both T :: T ( const T && ) and T :: T ( T && ) . If some user-defined move constructors are present, the user may still force the generation of the implicitly declared move constructor with the keyword default .

[ edit ] Deleted implicitly-declared move constructor

The implicitly-declared or defaulted move constructor for class T is defined as deleted in any of the following is true:

  • T has non-static data members that cannot be moved (have deleted, inaccessible, or ambiguous move constructors)
  • T has direct or virtual base class that cannot be moved (has deleted, inaccessible, or ambiguous move constructors)
  • T has direct or virtual base class with a deleted or inaccessible destructor
  • T has a user-defined move constructor or move assignment operator
  • T is a union and has a variant member with non-trivial copy constructor
  • T has a non-static data member or a direct or virtual base without a move constructor that is not trivially copyable.

[ edit ] Trivial move constructor

The implicitly-declared move constructor for class T is trivial if all of the following is true:

  • T has no virtual member functions
  • T has no virtual base classes
  • The move constructor selected for every direct base of T is trivial
  • The move constructor selected for every non-static class type (or array of class type) memeber of T is trivial

A trivial move constructor is a constructor that performs the same action as the trivial copy constructor, that is, makes a copy of the object representation as if by std:: memmove . All data types compatible with the C language (POD types) are trivially movable.

[ edit ] Implicitly-defined move constructor

If the implicitly-declared move constructor is not deleted or trivial, it is defined (that is, a function body is generated and compiled) by the compiler. For union types, the implicitly-defined move constructor copies the object representation (as by std:: memmove ). For non-union class types ( class and struct ), the move constructor performs full member-wise move of the object's bases and non-static members, in their initialization order, using direct initialization with an xvalue argument.

[ edit ] Notes

To make strong exception guarantee possible, user-defined move constructors should not throw exceptions. In fact, standard containers typically rely on std:: move_if_noexcept to choose between move and copy when container elements need to be relocated.

If both copy and move constructors are provided, overload resolution selects the move constructor if the argument is an rvalue (either prvalue such as a nameless temporary or xvalue such as the result of std:: move ), and selects the copy constructor if the argument is lvalue (named object or a function/operator returning lvalue reference). If only the copy constructor is provided, all argument categories select it (as long as it takes reference to const, since rvalues can bind to const references), which makes copying the fallback for moving, when moving is unavailable.

[ edit ] Example

  • Recent changes
  • Offline version
  • What links here
  • Related changes
  • Upload file
  • Special pages
  • Printable version
  • Permanent link
  • This page was last modified on 15 June 2012, at 14:13.
  • This page has been accessed 46 times.
  • Privacy policy
  • About cppreference.com
  • Disclaimers

Powered by MediaWiki

Learn C++

22.4 — std::move

Once you start using move semantics more regularly, you’ll start to find cases where you want to invoke move semantics, but the objects you have to work with are l-values, not r-values. Consider the following swap function as an example:

Passed in two objects of type T (in this case, std::string), this function swaps their values by making three copies. Consequently, this program prints:

As we showed last lesson, making copies can be inefficient. And this version of swap makes 3 copies. That leads to a lot of excessive string creation and destruction, which is slow.

However, doing copies isn’t necessary here. All we’re really trying to do is swap the values of a and b, which can be accomplished just as well using 3 moves instead! So if we switch from copy semantics to move semantics, we can make our code more performant.

But how? The problem here is that parameters a and b are l-value references, not r-value references, so we don’t have a way to invoke the move constructor and move assignment operator instead of copy constructor and copy assignment. By default, we get the copy constructor and copy assignment behaviors. What are we to do?

In C++11, std::move is a standard library function that casts (using static_cast) its argument into an r-value reference, so that move semantics can be invoked. Thus, we can use std::move to cast an l-value into a type that will prefer being moved over being copied. std::move is defined in the utility header.

Here’s the same program as above, but with a myswapMove() function that uses std::move to convert our l-values into r-values so we can invoke move semantics:

This prints the same result as above:

But it’s much more efficient about it. When tmp is initialized, instead of making a copy of x, we use std::move to convert l-value variable x into an r-value. Since the parameter is an r-value, move semantics are invoked, and x is moved into tmp.

With a couple of more swaps, the value of variable x has been moved to y, and the value of y has been moved to x.

Another example

We can also use std::move when filling elements of a container, such as std::vector, with l-values.

In the following program, we first add an element to a vector using copy semantics. Then we add an element to the vector using move semantics.

On the author’s machine, this program prints:

In the first case, we passed push_back() an l-value, so it used copy semantics to add an element to the vector. For this reason, the value in str is left alone.

In the second case, we passed push_back() an r-value (actually an l-value converted via std::move), so it used move semantics to add an element to the vector. This is more efficient, as the vector element can steal the string’s value rather than having to copy it.

Moved from objects will be in a valid, but possibly indeterminate state

When we move the value from a temporary object, it doesn’t matter what value the moved-from object is left with, because the temporary object will be destroyed immediately anyway. But what about lvalue objects that we’ve used std::move() on? Because we can continue to access these objects after their values have been moved (e.g. in the example above, we print the value of str after it has been moved), it is useful to know what value they are left with.

There are two schools of thought here. One school believes that objects that have been moved from should be reset back to some default / zero state, where the object does not own a resource any more. We see an example of this above, where str has been cleared to the empty string.

The other school believes that we should do whatever is most convenient, and not constrain ourselves to having to clear the moved-from object if its not convenient to do so.

So what does the standard library do in this case? About this, the C++ standard says, “Unless otherwise specified, moved-from objects [of types defined in the C++ standard library] shall be placed in a valid but unspecified state.”

In our example above, when the author printed the value of str after calling std::move on it, it printed an empty string. However, this is not required, and it could have printed any valid string, including an empty string, the original string, or any other valid string. Therefore, we should avoid using the value of a moved-from object, as the results will be implementation-specific.

In some cases, we want to reuse an object whose value has been moved (rather than allocating a new object). For example, in the implementation of myswapMove() above, we first move the resource out of a , and then we move another resource into a . This is fine because we never use the value of a between the time where we move it out and the time where we give a a new determinate value.

With a moved-from object, it is safe to call any function that does not depend on the current value of the object. This means we can set or reset the value of the moved-from object (using operator= , or any kind of clear() or reset() member function). We can also test the state of the moved-from object (e.g. using empty() to see if the object has a value). However, we should avoid functions like operator[] or front() (which returns the first element in a container), because these functions depend on the container having elements, and a moved-from container may or may not have elements.

Key insight

std::move() gives a hint to the compiler that the programmer doesn’t need the value of an object any more. Only use std::move() on persistent objects whose value you want to move, and do not make any assumptions about the value of the object beyond that point. It is okay to give a moved-from object a new value (e.g. using operator= ) after the current value has been moved.

Where else is std::move useful?

std::move can also be useful when sorting an array of elements. Many sorting algorithms (such as selection sort and bubble sort) work by swapping pairs of elements. In previous lessons, we’ve had to resort to copy-semantics to do the swapping. Now we can use move semantics, which is more efficient.

It can also be useful if we want to move the contents managed by one smart pointer to another.

Related content

There is a useful variant of std::move() called std::move_if_noexcept() that returns a movable r-value if the object has a noexcept move constructor, otherwise it returns a copyable l-value. We cover this in lesson 27.10 -- std::move_if_noexcept .

std::move can be used whenever we want to treat an l-value like an r-value for the purpose of invoking move semantics instead of copy semantics.

guest

A blog about C++ programming

Move Semantics: The Basics

Move Semantics

Move semantics was a new addition to C++ that arrived with C++ 11. Newer language standards have continued to expand and improve it. The feature is quite simple, but often misunderstood. I’m often reminded of that when I’m interviewing programmers.

Who will Find this Article Useful?

In this article I will cover all the basics of move semantics. This information will be useful for people that have never used move semantics but for people that are somehow familiar with the topic and use cases but don’t necessary use move semantics very often. The article will also be useful for people that want to dig deeper into the feature. And it will be useful for people that want to refresh their memory.

To benefit from this article to the fullest, you will need a good understanding of how copy constructors and assignment operators work, and you need to have a basic understanding of types and type casting.

1 – The case for Move Semantics

Before we look at the definition of move semantics, let us look at an example that will set up the premise of why move semantics exist.

1.1 – Setting the example

Let us assume that we are going to implement a struct that represents a memory block on the heap. The only thing this struct is responsible for is allocating the memory on construction and deallocating it on destruction. We can imagine that this struct is used by a complex memory allocation system. Let’s say that system is managing many instances of our struct, in other words, it is managing many memory buffers.

Here is the declaration of our struct:

We need to keep the example simple. And variables that could be needed for a robust solution, like used or free bytes and masks of all sorts, are out of the scope of this example.

1.2 – Using the Memory Buffer

Now let us also imagine that there is a free utility function that creates an array of buffers and returns the array. We can assume that this function is used by the complex memory allocation system in order to pre-allocate memory pools of different sizes.

Before C++ 11, no one would write this function in this way. Output parameters as pointer or reference will be used instead. This will make the function more complicated to implement, maintain and use. To explain why this was the case, let us have a look of how the “CreateMemoryPool” function is used. Let us assume that a bunch of pools of various sizes are created by the memory system in an “InitializePools” member function.

We will assume that we are not using any C++ 11 or newer additions to the language. We will also assume that for whatever reason the compiler will decide not to use Copy Elision to omit the copy of the return value of the “CreateMemoryPool(…)” function.

With all of these assumptions in play, calling the “CreateMemoryPool(…)” function will create a temporary return variable that will be used to assign to the member variables via the copy assignment operator of the std::vector. In other words, we are going to do a deep copy. This is very suboptimal way to write such code.

1.3 – The problem: deep copies can be very expensive

The problem with this scenario is that the local pool variable in the “CreateMemoryPool(…)” function, that stored the result of the function, will be copied into the m_PagePool and then destroyed. We are wasting a lot of cycles that way by executing extra instructions. We are also wasting cycles by allocating and deallocating memory (which is quite slow, generally speaking).

Before C++ 11, we would often reach for one of the following to minimize the allocations/deallocations caused by local and temporary variables:

  • Pass a pointer or a reference to the m_PagePool as input to the “CreateMemoryPool(…)” and let the function directly push back into the m_PagePool. In this way “CreateMemoryPool(…)” can return void, and the function is going to work directly on the variable that will store the final result of the function. And in this way we avoid copies. The first drawback is the extra parameter that is passed to the function, adding complexity. For example, doing this creates ambiguity when it comes to responsibility for the input state of that vector. Is it the callers responsibility to ensure that the vector is empty when invoking the function or will the function itself clear the vector? The second is the fact that passing a non-constant pointer or reference of the internal variable m_PagePool makes our code less safe because anyone can write code that does something bad to m_PagePool and the caller of “CreateMemoryPool(…)” loses all guarantees.
  • We can change the result of the function to return a vector of pointers to memory buffers, like so: vector<MemoryBuffer*>. This way we only copy the pointers when the “CreateMemoryPool(…)” function returns and there is no deep copying going on and no extra allocations/deallocations. The drawback to this is now the owner of the m_PagePool needs to worry about manually deallocating the pointers held by the vector, because the vector won’t do it in it own. Of course, we can use a vector of some of smart pointers to automate that part as well, but that also adds complexity.

1.4 – Move semantics solves the possible performance issue with deep copies

What we really want to do is keep the “CreateMemoryPool(…)” function implementation as it is, simple and safe, and move the result of the function directly into the m_PagePool variable without doing a deep copy, as if we are transferring water from one glass directly into another. Furthermore, we are doing even more copying by using the “push_back” function of the vector class and we want the push_back to also behave as if we are transferring water from one glass directly into another. C++ 11 and move semantics allows us to do exactly that. In the following sections, we are going to explore what move semantics are.

2 – Definition of Move Semantics

Move semantics are typically used to “steal” the resources held by another variable of the same type (e.g. pointers to dynamically-allocated objects, file descriptors, TCP sockets, I/O streams, running threads, etc.) and leave the source variable in some valid state, rather than making a deep copy of them.

The two most common use cases for move semantics are :

  • Performance: converting an expensive deep copy operation into a cheap move, like moving the data from a source string into a target string without having to allocate/deallocate.
  • Ownership semantics: Implementing user defined data types for which copying is not allowed but moving is, like the std::unique_ptr.

3 – Lvalues, Rvalues and Xvalues

To understand how move semantics work under the hood, we need to define a few other terms. Let’s start by looking at a pseudo-code that represents an assignment statement:

The left side of the statement is what historically is called Lvalue. And the right side of the statement is what historically is called Rvalue. Of course, because of the general nature of C++ things are often more complicated. Rvalues can appear on the left side, and Lvalues on the right side. Why that is the case is not relevant for this article.

3.1 – Easy way to differentiate between Lvalues and Rvalues

You might think that the fact that Lvalues and Rvalues can appear on either side is very confusing. Fortunately, there is a very simple rule we can use to remove all this confusion. A rule that will allow us to easily classify Lvalues and Rvalues in C++.

If a variable has an identifier that you have chosen yourself, then it is an Lvalue. And if a variable does not have a name that you have deliberately selected, then it is an Rvalue. To demonstrate this rule, let’s look at the following code snippets:

Here is another example:

3.2 – Double ampersands(&&) and the new operators

Prior to C++ 11, Rvalues and Lvalues were indistinguishable. The following example code would trigger the copy constructor and the copy assignment operator of the std::vector.

This is the Copy Constructor and the Copy Assignment Operator that would have been used in both cases:

To solve this problem, C++ 11 introduced Rvalue references, denoted by a double ampersands (&&). With this addition, we can now have two different copy constructors and assignment operators. One for Lvalues and one for Rvalues.

The following code snippet shows the declaration of the copy and the move constructors:

The following code snippet shows the declaration of the copy and the move assignment operators:

We can now revisit the example from above. And we can examine how in the cases where we have an Rvalue on the right hand side, the new move constructor and move assignment operators will be called instead of the copy constructor and copy assignment.

4 – Declaring Move Constructor and Move Assignment Operator

Now we know that C++ 11 introduced Rvalue references, denoted by a double ampersands (&&). And we know that we can declare a move constructor and a move assignment operator using the Rvalue type. Let’s declare them for our MemoryBuffer struct:

5 – Defining Move Constructor and Move Assignment Operator

We now know how to declare the move constructor and move assignment operator. It is now time to define them and actually implement the useful move semantics.

What we are doing in the move constructor and the move assignment is identical, except we also need to take care of self assignment in the move assignment operator. Let’s examine what we are doing in the move constructor:

  • In the initializer list, we are copying the source m_Buffer pointer into our own internal m_Buffer pointer. This is a simple pointer copy and not a deep copy. At this point both the source and the internal m_Buffer pointers point to the same memory address.
  • Then, also in the initializer list, we are copying the variable holding the size of the source buffer into the internal m_SizeInBytes variable.
  • Then, in the move constructor body, we set the source buffer pointer to nullptr. Effectively leaving the source pointer in a valid state, but also at this point completing the process of stealing the resource. After this the internal m_Buffer pointer points to where the source m_Buffer pointer used to point.
  • Finally, we reset the m_SizeInBytes of the source to 0, effectively leaving the source MemoryBuffer in a valid state.

For completeness, here is the the entire MemoryBuffer struct:

6 – Move Semantics in Action

With the new knowledge we acquired about Lvalues and Rvalues, as well as with the implementation of the move constructor and move assignment operator, we can now revisit the example we started with and see move semantics in action.

First, let us make a small change in the “CreateMemoryPool(…)” function.

To take advantage of the new move semantics and variadic templates, in C++ 11 a new version of the vector::push_back was added to the standard library. I recommend that you check the documentation, but in a nutshell, emplace_back will construct the new MemoryBuffer right in the memory location where it will be stored by the vector and in this way reducing the need to deep copy.

And finally, let us look at the “InitializePools” member function. Notice that the code is unchanged, but the compiler will call the move assignment operator and avoid deep copy and the extra allocations/deallocations, that are quite slow.

7 – Automatic vs. Manual Move

Looking at the “MemoryAllocationSystem::Initialize()” function, we can easily conclude that if move semantics were available to the compiler and if the types in question (std::vector and MemorBuffer in this case) supports move semantics, the compiler will detect the opportunity to move instead of copy. The reason for this is that the compiler will be able to see that the local variable created and returned by the “CreateMemoryPool(…)” is in fact an Rvalue.

The compiler is unable to detect every move opportunity. We can create a situation where we, as programmers, might have the intent to move the content of one array into another array (for whatever reasons) but the compiler will not be able to automatically detect our intent to move and will fallback to a deep copy. This of course happens when we have the intention to move an Lvalue into another Lvalue. Here is an example:

By default, the compiler will correctly assume that we ask for a deep copy. And if we really want to move, then we need to help the compiler a bit and turn the right hand Lvalues into Rvalue. To explicitly tell the compiler what our intent is, C++ 11 introduced a helper function: std::move . To utilize this new helper function, we can change our example to the following:

All std::move does is a cast. It casts the “ pool1 ” variable from an Lvalue reference (&) to an Rvalue reference (&&). Doing so tells the compiler which assignment operator it should call, because the variable type changes. And of course this is all based on standard function overloading rules. In its core, the assignment operator is a function, which is overloaded for two different input types (Lvalue reference and Rvalue reference).

8 – Xvalue

The following is a bit of an extra context and not absolutely necessary for this article, but I would rather mention it. The “ pool1 ” variable, in the example above, is technically an Xvalue after the std::move is executed. For all intent and purposes, you can treat it as an Lvalue, but the language implementers need a technical term for it. It means expiring value and it denotes an Lvalue object that can be reused after a move from it was executed. There are exactly three things that can be done to an Xvalue:

  • Copy assign to the Xvalue, turning it into an Lvalue.
  • Move assign to the Xvalue, turning it into an Lvalue.
  • Call the destructor when the Xvalue goes out of scope.

9 – Special Operators’ Rules

We all know that sometimes the compiler will generate constructors and other special operators on its own. The good news is that there are rules for when the compiler will do that. And now with the new move constructor and move assignment operator, these rules have been updated. For completeness, it is worth mentioning the most important rules here.

Rule 1 : Default move operations are generated only if no copy operations or destructor is user defined. This is because C++ assumes that if you need a destructor or you manually implemented copy operations, or both, then you are dealing with some sort of resource that needs special treatment. And because it is a resource, you need to implement the move operations yourself because you, as the expert, know best how this resources should behave.

Rule 2 : Default copy operations are generated only if there is no user defined move operations. The reasons here are are the same as in Rule 1. Note that =default and =delete count as user defined.

Rule 3 : You don’t need to implement move semantics or even copy semantics manually if all of the internal member variables are of types that are movable or copyable. For example, if we were to change the “char* m_Buffer” in our MemoryBuffer class to “unique_ptr<char> m_Buffer”, then we do not need to implement the move semantics ourselves, because the unique_ptr<T> class already supports move semantics.

10 – Parameters Convention

Move semantics is an optimization that is only applicable to some use cases. In general prefer simple and conventional ways of passing information. The following table illustrates an accepted convention for passing parameters and what types you should use. When in doubt, always check it.

Move Semantics and Parameters Convention

11 – Forwarding a Reference

For completeness, I need to cover one last topic. One more function was introduced together with std::move in C++ 11. And it was std::forward.

std::forward is pretty simple as it has only one use case. Its purpose is to preserve the value type, regardless if it is Lvalue or Rvalue, and pass it on. This is also called perfect forwarding. Typically a function accepting an Rvalue will attempt to move it and invalidate it, and when this is not the case, we can use std::forwad to pass on the Rvalue down the call-stack. The following example illustrates the use case.

For completeness, it is worth mentioning that In the code example above the input “T&& inArg” is called Forwarding reference . Forwarding references are a special kind of references that preserve the value category of a function argument. In this case calling “std::forward<T>(inArg)” will preserve the input argument and will forward it as Lvalue it if the input is an Lvalue, or it will forward it as Rvalue if the input is an Rvalue.

12 – Conclusion

In general, the concept of move semantics is quite simple and as programmers we should learn how and when to use it. The concept is built based on two fundamental C++ concepts: types and function/operator overloading. The following is a list of takeaway:

  • Pre-C++ 11, value semantics sometimes lead to unnecessary and possibly expensive deep copy operations.
  • C++ 11 introduces Rvalue references to distinguish from Lvalue references. And it also introduces std::move to cast from Lvalue to Rvalue.
  • From C++ 11 on, temporary variables are treated as Rvalues.
  • Moving POD or structs composed of PODs will not give you any benefits. To get benefits from move semantics you need some kind of resource (e.g. pointers to dynamically-allocated objects, file descriptors, TCP sockets, I/O streams, running threads, etc.).

13 – Source Code

The source code containing the MemoryBuffer example is here (under MoveSemantics ). You do not need a Github account to download it. When you open the repository, click on the Code button and choose Donwload ZIP .

14 – Credit

Special thanks to my colleagues for spending their personal time proofreading, challenge this article and helping me to make it better. It is a pleasure working with every one of you!

  • Anton Andersson : Senior Gameplay Programmer at IO Interactive.
  • Nils Iver Holtar : Lead AI Programmer at IO Interactive.

Please consider sharing this post if you find the information useful.

' src=

Post navigation

Previous post.

  • Language Feature
  • Code Snippet
  • Free Licenses

What is The Move Assignment Operator In Modern C++?

move assignment or constructor

The Move Assignment Operator is one of the great features of Object-Oriented Programming in  professional development . It complements features like the copy assignment operator, copy constructor, move constructor, and destructor. Since the C++11 standards, the move assignment operator is declared by using “operator=” and it allows you to move one object to another object. In this post, we explain what a move assignment operator is along with some C++ examples.

First, let’s remind ourselves what are the classes and objects in C++.

Table of Contents

What are classes and objects in C++?

Classes  are defined in C++ using the keyword  class  followed by the name of the class. Classes are the blueprint for the objects and they are user-defined data types that we can use in our program.  Objects  are an instantiation of a class, In C++ programming, because it is designed to be strongly object oriented most of the commands are associated with classes and objects, along with their attributes and methods. Here is a simple class example below.

What is a move assignment operator in C++?

The Move Assignment Operator  is an assignment operator that is a non-template non-static member function which is declared with the “ operator= “. When you create a class or a type that is move assignable (that you can move objects with the std::move ), it must have a public move assignment operator. Here is a simple syntax for the typical declaration of a move assignment operator.

Syntax (Since C++11),

Here is an example of a move assignment operator declaration in a class.

This is how you can move one object to another one with move assignment operator.

When the move assignment operator is called, lvalue object type of an assignment expression is the same type or implicitly converted type of the rvalue object. Move assignment operator is similar to changing two pointers of data blocks in C language. These can be, pointers to data blocks (i.e bitmaps), pointers to any structs, pointers to dynamically-allocated objects, I/O streams, running threads, file descriptors, TCP sockets, etc.

Is there a simple example of using the move assignment operator in C++?

The move assignment operator is default in any class declarations. This means you don’t need to declare it as above, let’s give examples without using it.

Let’s give a simple C++ example to move assignment operator with default option, here is a simple class.

Because this is default in any class declaration, and it is automatically declared. This class is same as below.

And here is how you can use move assignment operator with both class examples above.

Is there a full example of how to use the move assignment operator in C++?

Here is an example with a move assignment operator in a class that moves one object to another.

Here is the output.

As you see, in Modern C++, we can specialize the “ std::move ” on what to move or not, with the move assignment operator.

Is there a move assignment operator in a simple class?

Note that, a simple empty C++ class is perfectly equivalent to default implementations (Rule of Five) in a class. A modern compiler is able to provide all these special member functions (default implementations). For example, see this simple class below:

is exactly the same as the one below in modern C++.

What is The Move Assignment Operator In Modern C++ C++ Builder logo

C++ Builder  is the easiest and fastest C and C++ IDE for building simple or professional applications on the Windows, MacOS, iOS & Android operating systems. It is also easy for beginners to learn with its wide range of samples, tutorials, help files, and LSP support for code. RAD Studio’s C++ Builder version comes with the award-winning VCL framework for high-performance native Windows apps and the powerful FireMonkey (FMX) framework for cross-platform UIs.

There is a free C++ Builder Community Edition for students, beginners, and startups; it can be downloaded from  here . For professional developers, there are Professional, Architect, or Enterprise version.

move assignment or constructor

Oh hi there 👋 It’s nice to meet you.

Sign up to receive awesome c++ content in your inbox, every day..

We don’t spam! Read our privacy policy for more info.

Check your inbox or spam folder to confirm your subscription.

move assignment or constructor

About author

Yilmaz yoru, related posts, how to use skia in c++ builder 12, learn how to use clamp (std::clamp) in modern c++ 17 and beyond, what is the priority queue (std::priority_queue) in modern c++, what is the stack (std::stack) in modern c++.

  • Reduce development time and get to market faster with RAD Studio, Delphi, or C++Builder. Design. Code. Compile. Deploy. Start Free Trial Free C++Builder Community Edition

2020 Top 5 Market Trends Impacting Software Development Companies

Something Fresh

What people reading, ascii art: fun code spinning donut in 3d text form in c++, how to set up dev-c++ for your first project.

move assignment or constructor

Top C++ Compilers for Windows in 2020

Unicode strings in c++ on windows, how to program arduino with c++, newest questions tagged c++builder – stack overflow.

  • Boost library in C++Builder 12.1 (Modern)
  • Are there any compiler switches that affect how Variants are implemented? App A runs, but App B crashes
  • Using Indy HTTP under C++Builder to download file located behind a proxy

Newest questions tagged c++ – Stack Overflow

  • IN C++: Unhandled exception at 0x00007FF61A28BAF5 in Project1.exe: 0xC0000005: Access violation writing location 0x00000249474B4070
  • Clangd - jump to definition takes to header instead of cxx
  • Is non-template member function in class template generated only once in executable?

move assignment or constructor

LearnCPlusPlus.org is a C++ tutorial and learning platform for Windows developers using C++ to build Windows applications. It focuses on tools that allow rapid development and programming of both Win32 and Win64 applications. Additionally, it supports deploying apps to iOS.

© Copyright 2020 Embarcadero

  • Download C++Builder
  • Download Dev-C++
  • Learn Delphi
  • Embarcadero Blogs
  • DelphiFeeds

Move assignment operator

A move assignment operator of class T is a non-template non-static member function with the name operator = that takes exactly one parameter of type T && , const T && , volatile T && , or const volatile T && .

Explanation

  • Typical declaration of a move assignment operator.
  • Forcing a move assignment operator to be generated by the compiler.
  • Avoiding implicit move assignment.

The move assignment operator is called whenever it is selected by overload resolution , e.g. when an object appears on the left-hand side of an assignment expression, where the right-hand side is an rvalue of the same or implicitly convertible type.

Move assignment operators typically "steal" the resources held by the argument (e.g. pointers to dynamically-allocated objects, file descriptors, TCP sockets, I/O streams, running threads, etc.), rather than make copies of them, and leave the argument in some valid but otherwise indeterminate state. For example, move-assigning from a std::string or from a std::vector may result in the argument being left empty. This is not, however, a guarantee. A move assignment is less, not more restrictively defined than ordinary assignment; where ordinary assignment must leave two copies of data at completion, move assignment is required to leave only one.

Implicitly-declared move assignment operator

If no user-defined move assignment operators are provided for a class type ( struct , class , or union ), and all of the following is true:

  • there are no user-declared copy constructors;
  • there are no user-declared move constructors;
  • there are no user-declared copy assignment operators;
  • there are no user-declared destructors;

then the compiler will declare a move assignment operator as an inline public member of its class with the signature T& T::operator=(T&&) .

A class can have multiple move assignment operators, e.g. both T & T :: operator = ( const T && ) and T & T :: operator = ( T && ) . If some user-defined move assignment operators are present, the user may still force the generation of the implicitly declared move assignment operator with the keyword default .

The implicitly-declared (or defaulted on its first declaration) move assignment operator has an exception specification as described in dynamic exception specification (until C++17) exception specification (since C++17)

Because some assignment operator (move or copy) is always declared for any class, the base class assignment operator is always hidden. If a using-declaration is used to bring in the assignment operator from the base class, and its argument type could be the same as the argument type of the implicit assignment operator of the derived class, the using-declaration is also hidden by the implicit declaration.

Deleted implicitly-declared move assignment operator

The implicitly-declared or defaulted move assignment operator for class T is defined as deleted if any of the following is true:

  • T has a non-static data member that is const ;
  • T has a non-static data member of a reference type;
  • T has a non-static data member that cannot be move-assigned (has deleted, inaccessible, or ambiguous move assignment operator);
  • T has direct or virtual base class that cannot be move-assigned (has deleted, inaccessible, or ambiguous move assignment operator);

Trivial move assignment operator

The move assignment operator for class T is trivial if all of the following is true:

  • It is not user-provided (meaning, it is implicitly-defined or defaulted);
  • T has no virtual member functions;
  • T has no virtual base classes;
  • the move assignment operator selected for every direct base of T is trivial;
  • the move assignment operator selected for every non-static class type (or array of class type) member of T is trivial;

A trivial move assignment operator performs the same action as the trivial copy assignment operator, that is, makes a copy of the object representation as if by std::memmove . All data types compatible with the C language (POD types) are trivially move-assignable.

Implicitly-defined move assignment operator

If the implicitly-declared move assignment operator is neither deleted nor trivial, it is defined (that is, a function body is generated and compiled) by the compiler if odr-used .

For union types, the implicitly-defined move assignment operator copies the object representation (as by std::memmove ).

For non-union class types ( class and struct ), the move assignment operator performs full member-wise move assignment of the object's direct bases and immediate non-static members, in their declaration order, using built-in assignment for the scalars, memberwise move-assignment for arrays, and move assignment operator for class types (called non-virtually).

If both copy and move assignment operators are provided, overload resolution selects the move assignment if the argument is an rvalue (either a prvalue such as a nameless temporary or an xvalue such as the result of std::move ), and selects the copy assignment if the argument is an lvalue (named object or a function/operator returning lvalue reference). If only the copy assignment is provided, all argument categories select it (as long as it takes its argument by value or as reference to const, since rvalues can bind to const references), which makes copy assignment the fallback for move assignment, when move is unavailable.

It is unspecified whether virtual base class subobjects that are accessible through more than one path in the inheritance lattice, are assigned more than once by the implicitly-defined move assignment operator (same applies to copy assignment ).

See assignment operator overloading for additional detail on the expected behavior of a user-defined move-assignment operator.

Move assignment operator

A move assignment operator of class T is a non-template non-static member function with the name operator = that takes exactly one parameter of type T && , const T && , volatile T && , or const volatile T && . A type with a public move assignment operator is MoveAssignable .

[ edit ] Syntax

[ edit ] explanation.

  • Typical declaration of a move assignment operator
  • Forcing a move assignment operator to be generated by the compiler
  • Avoiding implicit move assignment

The move assignment operator is called whenever it is selected by overload resolution , e.g. when an object appears on the left side of an assignment expression, where the right-hand side is an rvalue of the same or implicitly convertible type.

Move assignment operators typically "steal" the resources held by the argument (e.g. pointers to dynamically-allocated objects, file descriptors, TCP sockets, I/O streams, running threads, etc), rather than make copies of them, and leave the argument in some valid but otherwise indeterminate state. For example, move-assigning from a std:: string or from a std:: vector leaves the right-hand side argument empty.

[ edit ] Implicitly-declared move assignment operator

If no user-defined move assignment operators are provided for a class type ( struct , class , or union ), and all of the following is true:

  • there are no user-declared copy constructors
  • there are no user-declared move constructors
  • there are no user-declared copy assignment operators
  • there are no user-declared destructors
  • the implicitly-declared move assignment operator would not be defined as deleted

then the compiler will declare a move assignment operator as an inline public member of its class with the signature T& T::operator= T(T&&)

A class can have multiple move assignment operators, e.g. both T & T :: operator = ( const T && ) and T & T :: operator = ( T && ) . If some user-defined move assignment operators are present, the user may still force the generation of the implicitly declared move assignment operator with the keyword default .

Because some assignment operator (move or copy) is always declared for any class, the base class assignment operator is always hidden. If a using-declaration is used to bring in the assignment operator from the base class, and its argument type could be the same as the argument type of the implicit assignment operator of the derived class, the using-declaration is also hidden by the implicit declaration.

[ edit ] Deleted implicitly-declared move assignment operator

The implicitly-declared or defaulted move assignment operator for class T is defined as deleted in any of the following is true:

  • T has a non-static data member that is const
  • T has a non-static data member of a reference type.
  • T has a non-static data member that cannot be move-assigned (has deleted, inaccessible, or ambiguous move assignment operator)
  • T has direct or virtual base class that cannot be move-assigned (has deleted, inaccessible, or ambiguous move assignment operator)
  • T has a non-static data member or a direct or virtual base without a move assignment operator that is not trivially copyable.
  • T has a direct or indirect virtual base class

[ edit ] Trivial move assignment operator

The implicitly-declared move assignment operator for class T is trivial if all of the following is true:

  • T has no virtual member functions
  • T has no virtual base classes
  • The move assignment operator selected for every direct base of T is trivial
  • The move assignment operator selected for every non-static class type (or array of class type) memeber of T is trivial

A trivial move assignment operator performs the same action as the trivial copy assignment operator, that is, makes a copy of the object representation as if by std:: memmove . All data types compatible with the C language (POD types) are trivially move-assignable.

[ edit ] Implicitly-defined move assignment operator

If the implicitly-declared move assignment operator is not deleted or trivial, it is defined (that is, a function body is generated and compiled) by the compiler. For union types, the implicitly-defined move assignment operator copies the object representation (as by std:: memmove ). For non-union class types ( class and struct ), the move assignment operator performs full member-wise move assignment of the object's bases and non-static members, in their initialization order, using built-in assignment for the scalars and move assignment operator for class types.

[ edit ] Notes

If both copy and move assignment operators are provided, overload resolution selects the move assignment if the argument is an rvalue (either prvalue such as a nameless temporary or xvalue such as the result of std:: move ), and selects the copy assignment if the argument is lvalue (named object or a function/operator returning lvalue reference). If only the copy assignment is provided, all argument categories select it (as long as it takes its argument by value or as reference to const, since rvalues can bind to const references), which makes copy assignment the fallback for move assignment, when move is unavailable.

The copy-and-swap assignment operator

T & T :: operator = ( T arg ) {     swap ( arg ) ;     return * this ; }

performs an equivalent of move assignment for rvalue arguments at the cost of one additional call to the move constructor of T, which is often acceptable.

[ edit ] Example

IMAGES

  1. What is move constructor and why it take r-value?

    move assignment or constructor

  2. Move Constructor/Assignment, Lambdas

    move assignment or constructor

  3. Copy Constructor vs Assignment Operator,Difference between Copy

    move assignment or constructor

  4. C++ : Default move constructor/assignment and deleted copy constructor

    move assignment or constructor

  5. C++ Tutorial: Rule of 5 [move constructor, move assignment operator

    move assignment or constructor

  6. What is a C++ Move Constructor?

    move assignment or constructor

VIDEO

  1. Move Move

  2. Obsolete attribute is ignored in constructor property assignment

  3. 113023 COSC 1337 C++ Class Dynamic Memory: Move constructor

  4. Making Photos Move

  5. Mastba C++ E18 Move Semantics: Constructor

  6. C++11 move constructor& move assignment(C++11移動建構元&移動指定算子)

COMMENTS

  1. Move Constructors and Move Assignment Operators (C++)

    This topic describes how to write a move constructor and a move assignment operator for a C++ class. A move constructor enables the resources owned by an rvalue object to be moved into an lvalue without copying. For more information about move semantics, see Rvalue Reference Declarator: &&. This topic builds upon the following C++ class ...

  2. 22.3

    C++11 defines two new functions in service of move semantics: a move constructor, and a move assignment operator. Whereas the goal of the copy constructor and copy assignment is to make a copy of one object to another, the goal of the move constructor and move assignment is to move ownership of the resources from one object to another (which is typically much less expensive than making a copy).

  3. Move assignment operator

    The move assignment operator is called whenever it is selected by overload resolution, e.g. when an object appears on the left-hand side of an assignment expression, where the right-hand side is an rvalue of the same or implicitly convertible type.. Move assignment operators typically "steal" the resources held by the argument (e.g. pointers to dynamically-allocated objects, file descriptors ...

  4. Difference between the move assignment operator and move constructor?

    A move constructor is executed only when you construct an object. A move assignment operator is executed on a previously constructed object. It is exactly the same scenario as in the copy case. Foo foo = std::move(bar); // construction, invokes move constructor. foo = std::move(other); // assignment, invokes move assignment operator.

  5. Move constructors

    the move constructor selected for every non-static class type (or array of class type) member of T is trivial. A trivial move constructor is a constructor that performs the same action as the trivial copy constructor, that is, makes a copy of the object representation as if by std::memmove. All data types compatible with the C language (POD ...

  6. Move Constructors in C++ with Examples

    The above program shows the unnecessarily calling copy constructor and inefficiently using the memory by copying the same data several times as it new object upon each call to copy constructor. Syntax of the Move Constructor: : data{ obj.data } // Nulling out the pointer to the temporary data. obj.data = nullptr;

  7. Move Assignment Operator in C++ 11

    The move constructor is called by the compiler when the argument is an rvalue reference which can be done by std::move() function. Example of Move Assignment Operator In this program, we will create a dynamic array class and create a user-defined move assignment operator.

  8. C++11 Tutorial: Introducing the Move Constructor and the Move

    The move constructor and the move assignment operator are the vehicles of move operations. It takes a while to internalize the principles of move semantics - and to design classes accordingly. However, the benefits are substantial. I would dare predicting that other programming languages will soon find ways to usher-in move semantics too.

  9. std::move in Utility in C++

    The move constructor was introduced in C++11.The need or purpose of a move constructor is to steal or move as many resources as it can from the source (original) object, as fast as possible, because the source does not need to have a meaningful value anymore, and/or because it is going to be destroyed in a moment anyway.So that one can avoid unnecessarily creating copies of an object and make ...

  10. Move constructors

    move assignment operator (C++11) destructor: Inheritance : base and derived classes: ... pure virtual functions and abstract classes A move constructor of class T is a non-template constructor whose first parameter is T &&, const T &&, volatile T &&, or const volatile T &&, and either there are no other parameters, or the rest of the parameters ...

  11. Move constructor and Move assignment c++11

    Move Semantics. These are two operations (Move constructor and Move assignment) that are used to move the value of object instead of copy. These will be provided by compiler by default like copy constructor, assign operator, default constructor and destructor, if we don't define by our-self.

  12. Move constructors

    T has direct or virtual base class that cannot be moved (has deleted, inaccessible, or ambiguous move constructors) T has direct or virtual base class with a deleted or inaccessible destructor T has a user-defined move constructor or move assignment operator T is a union and has a variant member with non-trivial copy constructor

  13. Move assignment operator

    The move assignment operator, like most C++ operators, can be overloaded. Like the copy assignment operator it is a special member function . If the move assignment operator is not explicitly defined, the compiler generates an implicit move assignment operator ( C++11 and newer) provided that copy / move constructors , copy assignment operator ...

  14. 22.4

    std::move. In C++11, std::move is a standard library function that casts (using static_cast) its argument into an r-value reference, so that move semantics can be invoked. Thus, we can use std::move to cast an l-value into a type that will prefer being moved over being copied. std::move is defined in the utility header.

  15. Move Semantics: The Basics

    And now with the new move constructor and move assignment operator, these rules have been updated. For completeness, it is worth mentioning the most important rules here. Rule 1: Default move operations are generated only if no copy operations or destructor is user defined. This is because C++ assumes that if you need a destructor or you ...

  16. What is The Move Assignment Operator In Modern C++?

    The Move Assignment Operator is one of the great features of Object-Oriented Programming in professional development. It complements features like the copy assignment operator, copy constructor, move constructor, and destructor. Since the C++11 standards, the move assignment operator is declared by using "operator=" and it allows you to move one object to another object. In this post,

  17. Move assignment operator

    then the compiler will declare a move assignment operator as an inline public member of its class with the signature T& T::operator=(T&&).. A class can have multiple move assignment operators, e.g. both T & T:: operator = (const T &&) and T & T:: operator = (T &&).If some user-defined move assignment operators are present, the user may still force the generation of the implicitly declared move ...

  18. Move assignment operator

    Forcing a move assignment operator to be generated by the compiler. Avoiding implicit move assignment. The move assignment operator is called whenever it is selected by overload resolution, e.g. when an object appears on the left side of an assignment expression, where the right-hand side is an rvalue of the same or implicitly convertible type.

  19. PDF C++ 11: Move Constructor Move Assignment Operator

    A move assignment operator is similar to a copy constructor except that before pilfering the source object, it releases any resources that its object may own. The move assignment operator performs four logical steps: Release any resources that (*this) currently owns. Pilfer other„s resource. Set other to a default state.

  20. Special members

    The copy assignment operator is also a special function and is also defined implicitly if a class has no custom copy nor move assignments (nor move constructor) defined. But again, the implicit version performs a shallow copy which is suitable for many classes, but not for classes with pointers to objects they handle its storage, as is the case ...

  21. C++ Tutorial: Rule of 5 [move constructor, move assignment operator]

    We continue our series on C++11 features you might have forgotten or never learned. Specifically, we will talk about the move constructor and move assignment...

  22. move constructor / move assignment

    move constructor / move assignment . move constructor / move assignment. kmce. Recently I have been practicing the different types of constructors and assingment operators. I am now doing the move constructor and assignment, and I think I have it somewhat correct, but I can not find any examples that have any class variables apart from the ...