Copy control part ii
1 / 7

Copy Control (Part II) - PowerPoint PPT Presentation

  • Uploaded on

Copy Control (Part II). Review: copy control consists of 5 distinct operations A copy constructor initializes an object by duplicating the const l-value that was passed to it by reference

I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
Download Presentation

PowerPoint Slideshow about 'Copy Control (Part II)' - clara

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
Copy control part ii
Copy Control (Part II)

  • Review: copy control consists of 5 distinct operations

    • A copy constructor initializes an object by duplicating the const l-value that was passed to it by reference

    • A copy-assignment operator (re)sets an object’s value by duplicating the const l-value passed to it by reference

    • A destructor manages the destruction of an object

    • A move constructor initializes an object by transferring the implementation from the r-value reference passed to it

    • A move-assignment operator (re)sets an object’s value by transferring the implementation from the r-value reference passed to it

  • Today we’ll focus on the last 2 operations and other features (introduced in C++11) like r-value references

    • I.e., features that support the new C++11 move semantics

Motivation for move semantics
Motivation for Move Semantics

  • Copy construction and copy-assignment may be expensive due to time/memory for copying

  • It would be more efficient to simply “take” the implementation from the passed object, it that’s ok

  • It’s ok if the passed object won’t be used afterward

    • E.g., if it was passed by value and so is a temporary object

    • E.g., if a special r-value reference says it’s ok to take from (as long as object remains in a state that’s safe to destruct)

  • Note that some objects require move semantics

    • I.e., types that don’t allow copy construction/assignment

    • E.g., unique_ptr, ifstream, thread, etc.

  • New for C++11: r-value references and move function

    • E.g., int i; int &&rvri = std::move(i);

Synthesized move operations
Synthesized Move Operations

  • Compiler will only synthesize a move operation if

    • Class does not declare any copy control operations, and

    • Every non-static data member of the class can be moved

  • Members of built-in types can be moved

    • E.g., by std::move etc.

  • User-defined types that have synthesized/defined version of the specific move operation can be moved

  • L-values are always copied, r-values can be moved

    • If there is no move constructor, r-values only can be copied

  • Can ask for a move operation to be synthesized

    • I.e., by using = default

    • But if cannot move all members, synthesized as = delete

R values l values and references to either
R-Values, L-Values, and References to Either

  • A variable is an l-value (has a location)

    • E.g., int i = 7;

  • Can take a regular (l-value) reference to it

    • E.g., int & lvri = i;

  • An expression is an r-value

    • E.g., i * 42

  • Can only take an r-value reference to it (note syntax)

    • E.g., int && rvriexp = i * 42;

  • Can only get r-value reference to l-value via move

    • E.g., int && rvri = std::move(i);

    • Promises that i won’t be used for anything afterward

    • Also, must be safe to destroy i (could be stack/heap/global)

Move constructors

Note r-value reference

Says it’s safe to take a’s implementation from it

Promises only subsequent operation will be destruction

Note constructor design

A lot like shallow copy constructor’s implementation

Except, zeroes out state of a

No sharing, current object owns the implementation

Object a is now safe to destroy (but is not safe to do anything else with afterward)

// takes implementation from a

IntArray::IntArray(IntArray &&a)

: size_(a.size_),

values_(a.values_) {

// make a safe to destroy

a.values_ = nullptr;

a.size_ = 0;


Move Constructors

Move assignment operators
Move-Assignment Operators

  • No allocation, so no exceptions to worry about

    • Simply free existing implementation (delete values_)

    • Then copy over size and pointer values from a

    • Then zero out size and pointer in a

  • This leaves assignment complete, a safe to destroy

    • Implementation is transferred from a to current object

      Array & Array::operator=(Array &&a) { // Note r-value reference

      if (&a != this) { // still test for self-assignment

      delete [] values_; // safe to free first (if not self-assigning)

      size_ = a. size_; // take a’s size value

      values_ = a.values_; // take a’s pointer value

      a.size_ = 0; // zero out a’s size

      a.values_ = nullptr; // zero out a’s pointer (now safe to destroy)


      return *this;


Move semantics and inheritance
Move Semantics and Inheritance

  • Base classes should declare/define move operations

    • If it makes sense to do so at all

    • Derived classes then can focus on moving their members

    • E.g., calling Base::operator= from Derived:: version

  • Containers further complicate these issues

    • Containers hold their elements by value

    • Risks slicing, other inheritance and copy control problems

  • So, put (smart) pointers, not objects, into containers

    • Access is polymorphic if destructors, other methods virtual

    • Smart pointers may help reduce need for copy control operations, or at least simplify cases where needed