copy construction and assignment - github pages · copy construction and assignment : assigning...

20
Copy Construction and Assignment Stephen P Levitt School of Electrical and Information Engineering University of the Witwatersrand 2019

Upload: others

Post on 27-Jun-2020

16 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Copy Construction and Assignment - GitHub Pages · Copy Construction and Assignment : Assigning Objects — The Assignment Operator 9 / 19 Assignment Must be an Atomic Operation Assignment

Copy Construction and Assignment

Stephen P Levitt

School of Electrical and Information EngineeringUniversity of the Witwatersrand

2019

Page 2: Copy Construction and Assignment - GitHub Pages · Copy Construction and Assignment : Assigning Objects — The Assignment Operator 9 / 19 Assignment Must be an Atomic Operation Assignment

Outline

1 Copying Objects — The Copy Constructor

2 Assigning Objects — The Assignment Operator

3 Copy Construction and Assignment Options

4 Derived Class Copy Construction and Assignment

Copy Construction and Assignment 1 / 19

Page 3: Copy Construction and Assignment - GitHub Pages · Copy Construction and Assignment : Assigning Objects — The Assignment Operator 9 / 19 Assignment Must be an Atomic Operation Assignment

Copy Construction

Copy construction creates a new object which is a duplicate of an existing object.

Account::Account(const Account& original)

Examples of when the copy constructor is called:

auto myAccount = Account{}; // calls the default constructor

auto anotherAccount = Account{myAccount}; // copy created on the stack

auto acc_ptr = make_unique<Account>(myAccount); // copy created on heap

void getAccountStatus(Account account) // pass-by-value copy created

Copy Construction and Assignment : Copying Objects — The Copy Constructor 2 / 19

Page 4: Copy Construction and Assignment - GitHub Pages · Copy Construction and Assignment : Assigning Objects — The Assignment Operator 9 / 19 Assignment Must be an Atomic Operation Assignment

The Compiler-Generated Copy Constructor

For the compiler-generated copy constructoreach data member of the class is copied using its own copy constructorprimitive types are simply copied

This is termed a memberwise copy.

Copy Construction and Assignment : Copying Objects — The Copy Constructor 3 / 19

Page 5: Copy Construction and Assignment - GitHub Pages · Copy Construction and Assignment : Assigning Objects — The Assignment Operator 9 / 19 Assignment Must be an Atomic Operation Assignment

Issues With the Compiler-Generated Copy Constructor

Sketch a memory map which illustrates the memory layout after the code in main hasbeen executed.

// in mainAddressBookEntry dana{"Dana","Dana.jpg"};AddressBookEntry tom{dana};// ----------------------------------------

class AddressBookEntry {public:AddressBookEntry(const string& name, const string& image_filename);// using compiler-generated copy constructor

private:string name_; // person's nameImage* image_ptr_; // image pointer

}

Copy Construction and Assignment : Copying Objects — The Copy Constructor 4 / 19

Page 6: Copy Construction and Assignment - GitHub Pages · Copy Construction and Assignment : Assigning Objects — The Assignment Operator 9 / 19 Assignment Must be an Atomic Operation Assignment

Assignment

Assignment sets an existing object equal to another existing object

Account yourAccount;

// calls the assignment operatoryourAccount = myAccount;

For the compiler-generated assignment operator:each data member is assigned in turn, using its own assignment operatorknown as memberwise assignment

Copy Construction and Assignment : Assigning Objects — The Assignment Operator 5 / 19

Page 7: Copy Construction and Assignment - GitHub Pages · Copy Construction and Assignment : Assigning Objects — The Assignment Operator 9 / 19 Assignment Must be an Atomic Operation Assignment

Consequences of Using the Compiler-Provided Copy Constructor andAssignment Operator

The compiler-generated copy constructor and assignment operator exhibit defaultmemberwise semantics and a shallow copy/assignment is made:

each data member of the class is copied in turn using its own copy constructor orassignment operatorstate will be shared if your class contains pointer data members

Typically, you want an independent copy.

Copy Construction and Assignment : Assigning Objects — The Assignment Operator 6 / 19

Page 8: Copy Construction and Assignment - GitHub Pages · Copy Construction and Assignment : Assigning Objects — The Assignment Operator 9 / 19 Assignment Must be an Atomic Operation Assignment

Assignment Issues — A Problematic Assignment Operatortom = dana;Does this work correctly? Assume the copy constructor for Image has been writtencorrectly.

2 void AddressBookEntry::operator=(const AddressBookEntry& rhs)3 {4 name_ = rhs.name_;5

6 delete image_ptr_;7 if (rhs.image_ptr_ != nullptr)8 // point to new image copy9 image_ptr_ = new Image{*(rhs.image_ptr_)};

10 else11 // point to null12 image_ptr_ = nullptr;13 }

Copy Construction and Assignment : Assigning Objects — The Assignment Operator 7 / 19

Page 9: Copy Construction and Assignment - GitHub Pages · Copy Construction and Assignment : Assigning Objects — The Assignment Operator 9 / 19 Assignment Must be an Atomic Operation Assignment

Problematic Assignment Operator: Clue — Withdrawing Cash from anATM; What Could Go Wrong?

Copy Construction and Assignment : Assigning Objects — The Assignment Operator 8 / 19

Page 10: Copy Construction and Assignment - GitHub Pages · Copy Construction and Assignment : Assigning Objects — The Assignment Operator 9 / 19 Assignment Must be an Atomic Operation Assignment

A Better (Atomic) Assignment Operator

1 void AddressBookEntry::operator=(const AddressBookEntry& rhs)2 {3 // use copy constructor to create temporary, assumes copy constructor4 // is written correctly5 AddressBookEntry temp{rhs};6

7 // swap temporary's data members with this object's8 name_.swap(temp.name_);9

10 // swap pointers11 Image* lhs_image_ptr = image_ptr_;12 image_ptr_ = temp.image_ptr_;13 temp.image_ptr_ = lhs_image_ptr;14

15 return;16 }

Copy Construction and Assignment : Assigning Objects — The Assignment Operator 9 / 19

Page 11: Copy Construction and Assignment - GitHub Pages · Copy Construction and Assignment : Assigning Objects — The Assignment Operator 9 / 19 Assignment Must be an Atomic Operation Assignment

Assignment Must be an Atomic Operation

Assignment must be atomic — it either happens completely or it does not happenat allAssignment can fail when constructing the temporary — then no assignmenttakes placeSwapping elements must be a no-fail operationAtomicity is a key concept for database transactions

Copy Construction and Assignment : Assigning Objects — The Assignment Operator 10 / 19

Page 12: Copy Construction and Assignment - GitHub Pages · Copy Construction and Assignment : Assigning Objects — The Assignment Operator 9 / 19 Assignment Must be an Atomic Operation Assignment

Returning the Left-Hand Operand

AddressBookEntry& AddressBookEntry::operator=(const AddressBookEntry& rhs)

{// use copy ctor to create temporaryAddressBookEntry temp{rhs};

// swap temporary's data members with this object'sname_.swap(temp.name_);

// swap pointersImage* lhs_image_ptr = image_ptr_;image_ptr_ = temp.image_ptr_;temp.image_ptr_ = lhs_image_ptr;

// return the lhs (good style)return *this;

}Copy Construction and Assignment : Assigning Objects — The Assignment Operator 11 / 19

Page 13: Copy Construction and Assignment - GitHub Pages · Copy Construction and Assignment : Assigning Objects — The Assignment Operator 9 / 19 Assignment Must be an Atomic Operation Assignment

Swapping data members

AddressBookEntry& AddressBookEntry::operator=(const AddressBookEntry& rhs)

{// use copy ctor to create temporaryAddressBookEntry temp{rhs};

// swap temporary's data members with this object'sname_.swap(temp.name_);

// swap pointersImage* lhs_image_ptr = image_ptr_;image_ptr_ = temp.image_ptr_;temp.image_ptr_ = lhs_image_ptr;

// return the lhs (good style)return *this;

}Copy Construction and Assignment : Assigning Objects — The Assignment Operator 12 / 19

Page 14: Copy Construction and Assignment - GitHub Pages · Copy Construction and Assignment : Assigning Objects — The Assignment Operator 9 / 19 Assignment Must be an Atomic Operation Assignment

Using a swap function

AddressBookEntry& AddressBookEntry::operator=(const AddressBookEntry& rhs)

{// use copy ctor to create temporaryAddressBookEntry temp{rhs};

// swap temporary with this object// must provide a no-fail (no throw) guaranteeswap(temp);

// return the lhs (good style)return *this;

}

Copy Construction and Assignment : Assigning Objects — The Assignment Operator 13 / 19

Page 15: Copy Construction and Assignment - GitHub Pages · Copy Construction and Assignment : Assigning Objects — The Assignment Operator 9 / 19 Assignment Must be an Atomic Operation Assignment

The Canonical Form of the Assignment Operator

Class& Class::operator=(const Class& rhs){

// use copy constructor to create a temporaryClass temp{rhs};

// swap temporary with this object// must provide a no-fail (no throw) guaranteeswap(temp);

// return the lhsreturn *this;

}

Copy Construction and Assignment : Assigning Objects — The Assignment Operator 14 / 19

Page 16: Copy Construction and Assignment - GitHub Pages · Copy Construction and Assignment : Assigning Objects — The Assignment Operator 9 / 19 Assignment Must be an Atomic Operation Assignment

Copy Constructor and Assignment Operator Options

Choose the appropriate option with regard to these functions:1 Let the compiler generate them automatically — make this explicit by using the

default keyword:Account(const Account& rhs) = default;Account& operator=(const Account& rhs) = default;

2 Write your own versions, taking full responsibility for construction and assignment3 Disallow copy construction and assignment:

Account(const Account& rhs) = delete;Account& operator=(const Account& rhs) = delete;

Copy Construction and Assignment : Copy Construction and Assignment Options 15 / 19

Page 17: Copy Construction and Assignment - GitHub Pages · Copy Construction and Assignment : Assigning Objects — The Assignment Operator 9 / 19 Assignment Must be an Atomic Operation Assignment

Derived Class Copy Construction and Assignment

Each class in the hierarchy should be responsible for its own data membersDerived classes should rely on their base classes to correctly copy construct orassign base class membersIn the absence of programmer-provided copy constructors/assignment operatorsthe compiler will revert to default memberwise initialisation or assignmentIf you provide your own copy constructor or assignment operator in a derived classyou are then responsible for copying/assigning all data members including those inthe base class by reusing base class functionality (DRY)

Copy Construction and Assignment : Derived Class Copy Construction and Assignment 16 / 19

Page 18: Copy Construction and Assignment - GitHub Pages · Copy Construction and Assignment : Assigning Objects — The Assignment Operator 9 / 19 Assignment Must be an Atomic Operation Assignment

Derived Class Copy Constructor Example

// A copy constructor is not actually required for ColourRect

ColourRect(const ColourRect& rhs):

// calls Rectangle's copy cstor, copies the Rectangle part ofColourRect

Rectangle{rhs},

// copies ColourRect data memberscolour_{rhs.colour_}

{}

Copy Construction and Assignment : Derived Class Copy Construction and Assignment 17 / 19

Page 19: Copy Construction and Assignment - GitHub Pages · Copy Construction and Assignment : Assigning Objects — The Assignment Operator 9 / 19 Assignment Must be an Atomic Operation Assignment

Derived Class Assignment Operator ExampleFollow the canonical form:

// An assignment op is not actually required for ColourRect

ColourRect& operator=(const ColourRect& rhs){

// use copy cstor to create temporaryColourRect temp{rhs};

// swap temporary with this object must provide a no-fail guaranteeswap(temp);

// return the lhsreturn *this;

}

Copy Construction and Assignment : Derived Class Copy Construction and Assignment 18 / 19

Page 20: Copy Construction and Assignment - GitHub Pages · Copy Construction and Assignment : Assigning Objects — The Assignment Operator 9 / 19 Assignment Must be an Atomic Operation Assignment

Derived Class Assignment Operator Example cont.

void ColourRect::swap(ColourRect& other){

// call Rectangle's swap to swap Rectangle's data membersRectangle::swap(other);

// swap ColourRect's data membersstd::swap(colour_, other.colour_);

}

Copy Construction and Assignment : Derived Class Copy Construction and Assignment 19 / 19