0% found this document useful (0 votes)
77 views20 pages

Move Constructor

This document discusses C++ move semantics and rvalue references. It introduces rvalue references as a way to avoid unnecessary copying and provide more efficient object transfer. It explains how rvalue references allow objects to be moved instead of copied, transferring resources without making new copies. This improves performance for returning objects from functions and other cases where temporary objects are used to initialize others. The document provides examples of move constructors and move assignment operators, and how the standard library containers and algorithms take advantage of moving to avoid unnecessary copying.

Uploaded by

eliaezekiel
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
77 views20 pages

Move Constructor

This document discusses C++ move semantics and rvalue references. It introduces rvalue references as a way to avoid unnecessary copying and provide more efficient object transfer. It explains how rvalue references allow objects to be moved instead of copied, transferring resources without making new copies. This improves performance for returning objects from functions and other cases where temporary objects are used to initialize others. The document provides examples of move constructors and move assignment operators, and how the standard library containers and algorithms take advantage of moving to avoid unnecessary copying.

Uploaded by

eliaezekiel
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 20

5/10/2016

C++ 11:
Move Semantics

Sandy Engelhardt
MITK Bugsquashing Seminar, March 2016
Welcome to the DKFZ!
Sandy Engelhardt
E 130
5/10/2016 | Page3 Rvalue References I

• Rvalue references is a small technical extension to the C++ language

• allow programmers to avoid logically unnecessary copying and to


provide perfect forwarding functions

• primarily meant to aid in the design of higher performance and more


robust libraries.

• a new category of reference variables for unnamed objects


(temporaries)

• typical examples of unnamed objects are return values of functions or


type-casts
Sandy Engelhardt
E 130
5/10/2016 | Page4 Rvalue References II

// standard C++ lvalue reference variable


std::string& ref;

// C++11 rvalue reference variable


std::string&& rrstr;

• lvalue – may appear on the left hand side of an assignment,


represents storage region locator value

• all the rest is non-lvalue or rvalue (because can appear on the


right hand side of assignment only)

An rvalue reference behaves just like an lvalue reference except that


it can bind to a temporary (an rvalue), whereas you can not bind a
(non const) lvalue reference to an rvalue.
Sandy Engelhardt
E 130
5/10/2016 | Page5 Copying Objects

• Hitherto, copying has been the only the object is never going to be used
means for transferring a state from for anything else, and thus, its value
one object to another can be moved into the destination
(* state of object = collective set of its non- object.
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.

• Using the value of a temporary


object e.g. these to initialize
another object or to assign its
value, does not require a copy:
Sandy Engelhardt
E 130
5/10/2016 | Page6 Example: Copy

string func()
{
string s;
//do something with s here
return s;
}
string mystr=func();

1. When func() returns, C++ constructs a temporary copy of s on the


caller‟s stack memory.
2. s is destroyed and the temporary is used for copy-constructing
mystr
3. the temporary itself is destroyed
Sandy Engelhardt
E 130
5/10/2016 | Page7 Copy vs. Move

• Copying a string requires the • Move operations tend to be faster


allocation of dynamic memory and than copying because they transfer
copying the characters from the an existing resource to a new
source. destination, whereas copying
requires the creation of a new
• Moving (new!) achieves the same
resource from scratch.
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.
Sandy Engelhardt
E 130
5/10/2016 | Page8 An addition to the fabulous 4…

• Default constructor
• Copy constructor
• Copy assignment operator
• Destructor

• C++11 introduces two new special member functions: the


move constructor and the move assignment operator.

• If a class doesn‟t have any user-declared special member


functions, C++ declares its remaining five (or six) special
member functions implicitly, e.g.

class S{};
Sandy Engelhardt
E 130
5/10/2016 | Page9 Move Constructor

• A move constructor looks like this:

//C++11 move constructor


MyClass::MyClass(MyClass&& other);

• It doesn‟t allocate new resources. Instead, it pilfers other„s


resources and then sets other to its default-constructed
state.

• The move constructor is much faster than a copy


constructor because:
• it doesn‟t allocate memory
• It doesn‟t copy memory buffers
Sandy Engelhardt
E 130
5/10/2016 | Page10 Example Move Constructor

class MemoryPage //C++11 move constructor


{ MemoryPage(MemoryPage&& other):
size_t size; size(0), buf(nullptr)
char * buf; {
// pilfer other’s resource
public:
size=other.size;
buf=other.buf;
//constructor
explicit MemoryPage(int sz=512):
size(sz), buf(new char [size]) {} // reset other
other.size=0;
//destructor other.buf=nullptr;
~MemoryPage(){delete[] buf;} }

//C++03 copy constructor //C++11 move assignment operator


MemoryPage(const MemoryPage&); MemoryPage&
MemoryPage::operator=(MemoryPage&&
//C++03 assignment operator other)
MemoryPage& operator=(const MemoryPage&); {…}
};
Sandy Engelhardt
E 130
5/10/2016 | Page11 Examples

// function returning a MemoryPage object


MemoryPage fn();

// default constructor
MemoryPage foo;

// copy constructor
MemoryPage bar = foo;

// move constructor
MemoryPage baz = fn();

// copy assignment
foo = bar;

// move assignment
baz = MemoryPage();
Sandy Engelhardt
E 130
5/10/2016 | Page12 STL

• 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:

const T& for lvalue arguments

T&& for rvalue arguments

• All containers are “move-aware”


• New algorithms: move, move_forward
• New iterator adaptor: move_iterator
• Optimized swap for movable types
Sandy Engelhardt
E 130
5/10/2016 | Page13 Hands-on Example

• The following program populates a vector with MemoryPage


objects using two push_back()calls:

#include <vector> #include <vector>


using namespace std; using namespace std;

int main() int main()


{ {
vector<MemoryPage> vm; vector<MemoryPage> vm;

vm.push_back(MemoryPage(1024)); MemoryPage mp1(1024);


vm.push_back(MemoryPage(2048)); vm.push_back(mp1);
} }

 arguments are rvalues:  arguments are lvalues:


push_back(T&&)is called push_back(const T&)is called

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.
Sandy Engelhardt
E 130
5/10/2016 | Page14 lvalue --- to --- rvalue

• You can enforce the selection of push_back(T&&)


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:

// calls push_back(T&&)
vm.push_back(std::move(mp));
Sandy Engelhardt
E 130
5/10/2016 | Page15 What happens to a moved-from object?

o1 o2
move-from object move-to object

• state is unspecified, though valid !

assumption:
• object no longer owns any resources and
its state is similar to that of an empty (as if
default-constructed) object (though valid)
Sandy Engelhardt
E 130
5/10/2016 | Page16 Conclusion

• It may seem as if push_back(T&&) is always the best


choice because it eliminates unnecessary copies.

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 !!
Sandy Engelhardt
E 130
5/10/2016 | Page17 References

• http://blog.smartbear.com/c-plus-plus/c11-tutorial-introducing-the-
move-constructor-and-the-move-assignment-operator/

• http://www.open-
std.org/jtc1/sc22/wg21/docs/papers/2006/n2027.html

• http://de.slideshare.net/oliora/hot-c-rvalue-references-and-move-
semantics

• https://www.youtube.com/watch?v=IOkgBrXCtfo

http://www.nosid.org/cxx11-about-move-semantics.html

• http://www.cplusplus.com/doc/tutorial/classes2/
Thank you
for your attention!

Further information on www.dkfz.de


Sandy Engelhardt
E 130
5/10/2016 | Page19 Further reading: Move Assignment Operator

• 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:

1. Release any resources that (*this) currently owns.


2. Pilfer other„s resource.
3. Set other to a default state.
4. Return (*this).
Sandy Engelhardt
E 130
Further reading: Example Move
5/10/2016 | Page20 Assignment Operator

• //C++11 move assignment operator


MemoryPage& MemoryPage::operator=(MemoryPage&& other)
{
if (this!=&other)
{
// release the current object’s resources
delete[] buf;
size=0;

• // pilfer other’s resource


size=other.size;
buf=other.buf;
// reset other
other.size=0;
other.buf=nullptr;
}
return *this;
}

You might also like