Copy Control (Part I) - PowerPoint PPT Presentation

About This Presentation
Title:

Copy Control (Part I)

Description:

Copy Control (Part I) Copy control consists of 5 distinct operations A copy constructor initializes an object by duplicating the const l-value that was passed to it ... – PowerPoint PPT presentation

Number of Views:53
Avg rating:3.0/5.0
Slides: 9
Provided by: wus81
Category:

less

Transcript and Presenter's Notes

Title: Copy Control (Part I)


1
Copy Control (Part I)
  • 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 objects
    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 objects
    value by transferring the implementation from the
    r-value reference passed to it
  • Today well focus on the first 3 operations and
    will defer the others (introduced in C11) until
    next time
  • The others depend on the new C11 move semantics

2
Basic Copy Control Operations
  • A copy constructor or copy-assignment operator
    takes a reference to a (usually const) instance
    of the class
  • Copy constructor initializes a new object from it
  • Copy-assignment operator sets objects value from
    it
  • In either case, original the object is left
    unchanged (which differs from the move versions
    of these operations)
  • Destructor takes no arguments (except implicit
    this)
  • Copy control operations for built-in types
  • Copy construction and copy-assignment copy values
  • Destructor of built-in types does nothing (is a
    no-op)
  • Compiler-synthesized copy control operations
  • Just call that same operation on each member of
    the object
  • Uses defined/synthesized definition of that
    operation for user-defined types (see above for
    built-in types)

3
Preventing or Allowing Basic Copy Control
  • Old (C03) way to prevent compiler from
    generating a default constructor, copy
    constructor, destructor, or assignment operator
    was somewhat awkward
  • Declare private, dont define, dont use within
    class
  • This works, but gives cryptic linker error if
    operation is used
  • New (C11) way to prevent calls to any method
  • End the declaration with delete (and dont
    define)
  • Compiler will then give an intelligible error if
    a call is made
  • C11 allows a constructor to call peer
    constructors
  • Allows re-use of implementation (through
    delegation)
  • Object is fully constructed once any constructor
    finishes
  • C11 lets you ask compiler to synthesize
    operations
  • Explicitly, but only for basic copy control,
    default constructor
  • End the declaration with default (and dont
    define)

4
Shallow Copy Construction
  • // just uses the array thats already in the
    other object
  • IntArrayIntArray(const IntArray a)
  • size_(a.size_),
  • values_(a.values_)
  • There are two ways to copy
  • Shallow re-aliases existing resources
  • E.g., by copying the address value from a pointer
    member variable
  • Deep makes a complete and separate copy
  • I.e., by following pointers and deep copying what
    they alias
  • Version above shows shallow copy
  • Efficient but may be risky (why?)
  • Usually want no-op destructor, aliasing via
    shared_ptr

5
Deep Copy Construction
  • // makes its own copy of the array
  • IntArrayIntArray(const IntArray a)
  • size_(0), values_(nullptr)
  • if (a.size_ gt 0)
  • // new may throw bad_alloc,
  • // set size_ after it succeeds
  • values_ new inta.size_
  • size_ a.size_
  • // could use memcpy instead
  • for (size_t i 0
  • i lt size_ i)
  • values_i a.values_i
  • This code shows deep copy
  • Safe no shared aliasing, exception aware
    initialization
  • But may not be as efficient as shallow copy in
    many cases
  • Note trade-offs with arrays
  • Allocate memory once
  • More efficient than multiple calls to new (heap
    search)
  • Constructor and assignment called on each array
    element
  • Less efficient than block copy
  • E.g., using memcpy()
  • But sometimes necessary
  • i.e., constructors, destructors establish needed
    invariants

6
Swap Trick for Copy-Assignment
  • Cleanup/assignment succeed or fail together
  • class Array
  • public
  • Array(unsigned int) // assume constructor
    allocates memory
  • Array(const Array ) // assume copy
    constructor makes a deep copy
  • Array() // assume destructor calls delete on
    values_
  • Array operator(const Array a)
  • private
  • size_t size_
  • int values_
  • Array Arrayoperator(const Array a) //
    return ref lets us chain
  • if (a ! this) // note test for
    self-assignment (safe, efficient)
  • Array temp(a) // copy constructor makes
    deep copy of a
  • swap(temp.size_, size_) // note
    unqualified calls to swap
  • swap(temp.values_, values_) // (do
    user-defined or stdswap)
  • return this // previous values_ cleaned up
    by temps destructor

7
Constructors and Destructors are Inverses
  • Constructors initialize
  • At the start of each objects lifetime
  • implicitly called when object is created
  • Destructors clean up
  • Implicitly called when an object is destroyed
  • E.g., when stack frame where it was declared goes
    out of scope
  • E.g., when its address is passed to delete
  • E.g., when another object of which it is a member
    is being destroyed

IntArrayIntArray(unsigned int u) size_(0),
values_(nullptr) // exception safe semantics
values_ new int u size_
u IntArrayIntArray() // deallocates
heap memory // that values_ points to, // so
its not leaked // with deep copy, object //
owns the memory delete values_ // the
size_ and values_ // member variables are //
themselves destroyed // after destructor
body
8
More on Initialization and Destruction
  • Initialization follows a well defined order
  • Base class constructor is called
  • That constructor recursively follows this order,
    too
  • Member constructors are called
  • In order members were declared
  • Good style to list in that order (a good compiler
    may warn if not)
  • Constructor body is run
  • Destruction occurs in the reverse order
  • Destructor body is run, then member destructors,
    then base class destructor (which recursively
    follows reverse order)
  • Make destructor virtual if members are virtual
  • Or if class is part of an inheritance hierarchy
  • Avoids slicing ensures destruction starts at
    the most derived class destructor (not at some
    higher base class)
Write a Comment
User Comments (0)
About PowerShow.com