1 / 58

Copy Control

Copy Control. Joe Meehean. More Class Responsibilities. When making a new type (i.e., class) we must specify what happens when it is: Copied Assigned Destroyed. Copy Constructor. Used to create a new copy of a class object Takes a single parameter of same class type (usually const )

heaton
Download Presentation

Copy Control

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. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Copy Control Joe Meehean

  2. More Class Responsibilities • When making a new type (i.e., class) we must specify what happens when it is: • Copied • Assigned • Destroyed

  3. Copy Constructor • Used to create a new copy of a class object • Takes a single parameter of same class type (usually const) • Has no return type • Declaration syntax • Class(const Class& orig) • e.g., IntMatrix(constIntMatrix& orig);

  4. Copy Constructor • Usage syntax • Class varname(origname) • e.g., IntMatrix a(4,4);IntMatrix b(a); • Definition requirements • must initialize all data members • data members should match values of original’s data members

  5. Copy Constructor // (header) .h classHitSong{ Song hit_song_; intchart_rank_; intsingles_sold_; HitSong( Song& song, intchart_rank, intsingles_sold); HitSong( constHitSong& orig); };

  6. Copy Constructor HitSong::HitSong(constHitSong& orig) : hit_song_(orig.hit_song_), chart_rank_(orig.chart_rank_), singles_sold_(orig.singles_sold_) { // nothing to do here } • Note: this constructor can access private data of orig • Because both this and orig are instances of HitSong

  7. Copy Constructor • What if we don’t write a copy constructor? • Compiler creates one for us • called the synthesized copy constructor • created even if we define other constructors • Synthesized copy constructor • performs memberwise initialization of member data • initializes each member variable by copying original member variable • if member variable is a built-in (primitive), just copies the bits • if member variable is a class, uses the class’s copy constructor • if member variable is an array, copies each element

  8. Copy Constructor • How do we prevent copies of our class? • Approach 1: make copy constructor private • prevents non-class code from making copies • friends and member functions of class can still make copies • Approach 2: make undefined, private copy constructor • declare it • e.g., IntMatrix(constIntMatrix& orig); • do not define it • perfectly legal • non-class code gets compiler errors • class code and friends get linking errors

  9. Copy Constructor • When is it used • Explicitly in code • e.g., IntMatrix b(a); • Passing class instance as an argument to a function • non-reference • e.g., flip(IntMatrix a); • Returning a non-reference instance from a function • e.g., return a;

  10. Copy Constructor • When is it used • Explicitly initializing an array Song songs[] = { Song(“Simply Irresistable”, “Robert Palmer”), Song(“The Power of Love”, “Huey Lewis & The News”), Song(“In the Air Tonight”, “Phil Collins”) }; • Uses constructor to create temporary Songs • Initializes array using copies of temporary Songs

  11. Copy Constructor • Classes best practices: always define a • default constructor • copy constructor

  12. Questions?

  13. Assignment Operator • If you implement a class,you need to control what happens during an assignment • e.g., b = a; • make sure data is copied correctly from a to b • How do we write a function for an operator?

  14. Assignment Operator • How do we write a function for an operator? • syntax: return_type operator symbol(type operand1, type operand 2, …) • e.g.,int operator + ( constint& a, constint& b); • The assignment operator (=) often returns a reference to the assigned variable • allows: a = b = c; • e.g.,int& operator = (int& a, int& b); • More on this in future lectures

  15. Assignment Operator • When we write an operator function for a class,the first parameter is implicitly the this parameter • Assignment operator for a class declaration syntax • Class& operator =(const Class& rhs) • e.g., HitSong& operator =(constHitSong& rhs) • Assignment operator for a class definition syntax • Class& Class::operator =(const Class& rhs){ … } • e.g., HitSong& HitSong::operator =(constHitSong& rhs)

  16. Assignment Operator • When doing assignment we are copying values from one instance of a class to another • unlike copy constructor, both instances are already initialized Song aSong(“Twilight Zone”, “Golden Earring”); Song bSong(“Radar Love”, “Golden Earring”); aSong = bSong;

  17. Assignment Operator HitSong& HitSong::operator =(constHitSong& rhs) { if( this != &rhs ){ this->song_ = rhs.song_; this->chart_rank_ = rhs.chart_rank_; this->singles_sold_ = rhs.singles_sold_; } return *this; }

  18. Assignment Operator HitSong& HitSong::operator =(constHitSong& rhs) { if( this != &rhs ){ this->song_ = rhs.song_; this->chart_rank_ = rhs.chart_rank_; this->singles_sold_ = rhs.singles_sold_; } return *this; }

  19. Assignment Operator HitSong& HitSong::operator =(constHitSong& rhs) { if( this != &rhs ){ this->song_ = rhs.song_; this->chart_rank_ = rhs.chart_rank_; this->singles_sold_ = rhs.singles_sold_; } return *this; }

  20. Assignment Operator • What if we don’t write an assignment operator? • Compiler makes a synthesized assignment operator • Performs memberwise assignment • each member variable is assigned member variable from rhs • built-ins use a bitwise assignment • classes uses their own assignment operator • arrays are assigned element by element • Returns *this

  21. Assignment Operator • What happens in this code? Song aSong(“Hotel California”, “Eagles”); Song b = aSong;

  22. Assignment Operator • What happens in this code? Song aSong(“Hotel California”, “Eagles”); Song b = aSong; • b is created using Song’s copy constructor

  23. Assignment Operator • Classes best practices: always define a • default constructor • copy constructor • assignment operator

  24. Questions?

  25. Destructor • How do we clean up the memory we allocated with the constructor? • Each class needs a destructor method • one more responsibility of class creator • specifies how to clean up memory allocated for member data • complement of constructors

  26. Destructor • When is the destructor called? • Automatic objects • automatically destroyed when they go out of scope intHitSong::func(){ Song aSong(“Could well be in”, “The Streets”); // other stuff ... } aSong is destroyed using its destructor

  27. Destructor • When is the destructor called? • Dynamically allocated objects • destroyed explicitly using delete intHitSong::func(){ Song * pSong = new Song( “Could well be in”, “The Streets”); // other stuff ... delete pSong; } Memory pointed to by pSong is destroyed using its destructor

  28. Destructor • When is the destructor called? • Dynamically allocated objects • if never deleted, it is never destroyed intHitSong::func(){ Song * pSong = new Song( “Could well be in”, “The Streets”); // other stuff ... } pSong lives on forever. We cannot get access to it either.

  29. Destructor • When is the destructor called? • Arrays of objects • deleted when array is destroyed intHitSong::func(){ Song songs[10]; // other stuff ... } each Song in songs is destroyed using its destructor

  30. Destructor • Declaration syntax • virtual ~Class(); • e.g., virtual ~Song(); • takes no parameters • has not return type • ignore what virtual means for now, just include it • Definition syntax • Class::~Class(){ • e.g., Song::~Song(){

  31. Destructor • Usage syntax • how do we call the destructor • you don’t, its called automatically in cases described earlier

  32. Destructor • What happens if we don’t define one? • Compiler defines a destructor for you. • destroys each non-static member variable • using same rules like the object went out of scope • destroys them in reverse order of declaration • What happens if we do define one • compiler defines one even if you define one too • compiler runs its destructor after yours

  33. Destructor • Why bother to define a destructor if the compiler already does it for you? • May need to deallocate non-automatic resources • dynamically allocated memory • close open files • amongst others (more on this in OS) • What should our destructor do? • if you don’t dynamically allocate memory (or other resources) • nothing

  34. Destructor • Classes best practices: always define a • default constructor • copy constructor • assignment operator • destructor • Actually… • you should decide for yourself, except • Big Three: copy constructor, assignment operator, and destructor • if you define a one of Big Three, should always define other two

  35. Questions?

  36. Copy Control and Pointers • Pointers make copy control (Big Three) more difficult • Class designer must make one of two choices: • Shallow copy • copy and assignment should copy only the pointer • Deep copy • copy and assignment allocate new memory and copy object pointer points to

  37. Copy Control and Pointers • Assume Song::Song( const char* name,const char *artist){ name_ = new char[512]; // SHOULD USE STRLEN artist_ = new char[512]; strcpy(name_, name); strcpy(artist_, artist); } void Song::setArtist(const char* artist){ strcpy(artist_, artist); // SHOULD CHECK LENGTH } void Song::deleteName(){ delete name_; name_ = NULL; }

  38. Copy Control and Pointers • Shallow copying Song::Song(const Song& orig){ name_ = orig.name_; artist_ = orig.artist_; }

  39. Copy Control and Pointers • Shallow copying void main(){ Song aSong(“All along the watchtower”, “Bob Dylan”); } aSong : Bob Dylan artist_ name_ All along…

  40. Copy Control and Pointers • Shallow copying void main(){ Song aSong(“All along the watchtower”, “Bob Dylan”); Song bSong(aSong); } bSong : aSong : Bob Dylan artist_ artist_ name_ name_ All along…

  41. Copy Control and Pointers • Shallow copying void main(){ Song aSong(“All along the watchtower”, “Bob Dylan”); Song bSong(aSong); aSong.setArtist(“Jimi Hendrix”); } bSong : aSong : Jimi Hendrix artist_ artist_ name_ name_ All along…

  42. Copy Control and Pointers • Shallow copying void main(){ Song aSong(“All along the watchtower”, “Bob Dylan”); Song bSong(aSong); aSong.setArtist(“Jimi Hendrix”); aSong.deleteName(); } bSong : aSong : Jimi Hendrix artist_ artist_ name_ name_ All along… Director’s Cut

  43. Copy Control and Pointers • Dangers of shallow copies • data modified out from under you • data destroyed, left pointing at garbage • program crashes or acts strangely

  44. Copy Control and Pointers • Deep copying Song::Song(constSong& orig){ name_ = new char[strlen(orig.name_)+1]; artist_ = new char[strlen(orig.artist_)+1]; strcpy(name_, orig.name_); strcpy(artist_, orig.artist_); }

  45. Copy Control and Pointers • Deep copying void main(){ Song aSong(“All along the watchtower”, “Bob Dylan”); } aSong : Bob Dylan artist_ name_ All along…

  46. Copy Control and Pointers • Deep copying void main(){ Song aSong(“All along the watchtower”, “Bob Dylan”); Song bSong(aSong); } bSong : aSong : Bob Dylan Bob Dylan artist_ artist_ name_ name_ All along… All along…

  47. Copy Control and Pointers • Deep copying void main(){ Song aSong(“All along the watchtower”, “Bob Dylan”); Song bSong(aSong); aSong.setArtist(“Jimi Hendrix”); } bSong : aSong : Jimi Hendrix Bob Dylan artist_ artist_ name_ name_ All along… All along…

  48. Copy Control and Pointers • Deep copying void main(){ Song aSong(“All along the watchtower”, “Bob Dylan”); Song bSong(aSong); aSong.setArtist(“Jimi Hendrix”); aSong.deleteName(); } bSong : aSong : Jimi Hendrix Bob Dylan artist_ artist_ name_ name_ All along… All along… Director’s Cut

  49. Copy Control and Pointers • If you don’t define a copy constructor or an assignment operator • synthesized versions perform a shallow copy • If you define a deep copy constructor and assignment operator, but not a destructor • you will leak memory

  50. Copy Control and Pointers • Deep copying Song::operator =(const Song& orig){ if( this != &orig ){ delete name_; delete artist_; name_ = new char[strlen(orig.name_)+1]; artist_ = new char[strlen(orig.artist_)+1]; strcpy(name_, orig.name_); strcpy(artist_, orig.artist_); } return *this; }

More Related