Lecture 6

• Copy constructor • Pointer this • Assignment operator • Recursive data structures – Example: single linked list • Friend functions

Lec 5 Programming in C++ 1

A constructor for Employee

• Constructor below may lead to problems

Employee::Employee( const char *first, const char *last) { firstname = first; lastname = last; }

– A better constructor should be such that each object has its own copy of the strings firstname and lastname

Lec 5 Programming in C++ 2

1 Another Constructor for Employee See Fig07_17_19 • A better constructor in Code of Lec 5

Employee::Employee( const char *first, const char *last ) { firstName = new char[ strlen( first ) + 1 ]; strcpy( firstName, first );

lastName = new char[ strlen( last ) + 1 ]; strcpy( lastName, last );

}

•Don’t forget: #include

Lec 5 Programming in C++ 3

Destructor for Employee

• Do we need to program it? Why? – YES! To avoid memory leaks.

Employee::~Employee() { delete [] firstName; // deallocate memmory delete [] lastName; // deallocate memory }

Lec 5 Programming in C++ 4

2 More on constructors …

• Consider the following declaration

Employee E1(“Anna”, “Pettersson”);

– Assume we would like to create another employee with same data as E1

Employee E2(E1);

– We need another constructor to create a copy of E1 → Copy Constructor

Lec 5 Programming in C++ 5

A copy constructor for Employee class

Employee::Employee(const Employee &E) { firstName = new char[strlen(E.firstName) + 1]; strcpy(firstName, E.firstName);

lastName = new char[strlen(E.lastName) + 1]; strcpy(lastName, E.lastName);

}

Lec 5 Programming in C++ 6

3 Copy Constructor

ƒ Copy constructor is automatically called when needed to make a copy of an object 1. Objects passed-by-value as function arguments 2. Objects returned from functions

ƒ Why is the argument of the copy constructor passed-by-reference?

Employee::Employee(const Employee E) { … } Passing-by-value does not work!!

Lec 5 Programming in C++ 7

Moving on to this

• Recall class Time and assume the following functions are added void Time::setHour( int h ) { hour = ( h >= 0 && h < 24 ) ? h : 0; } void Time::setMinute( int m ) { minute = ( m >= 0 && m < 60 ) ? m : 0;} void Time::setSecond( int s ) { second = ( s >= 0 && s < 60 ) ? s : 0; }

Lec 5 Programming in C++ 8

4 Cascading Function Calls

•Examples: The result of an assignment L = R; int x, y, w; is the R-value x = y = w = 9; cout << x << ““<< y << endl;

• We would like to write: returns Time T(5, 30, 22); void Time *ptr = &T; T.setMinute(18).setSecond(30); Not possible!!! ptr->setHour(18)->setMinute(15);

Lec 5 Programming in C++ 9

The this Pointer • Allows object to access own address (refer to itself)

Time T(5, 30, 22); In function setMinute T.setMinute(18); this points to object T

Time& Time::setHour( int h ){ hour = ( h >= 0 && h < 24 ) ? h : 0; Why not ? return *this; Time Why to return Time&? }

Lec 5 Programming in C++ 10

5 Assignment Operator • Why to re-program it? – There is an assignment ( = ) operator by default – It should be possible to cascade Employee E1(“Anna”, “Pettersson”); Employee E2, E3(“Maria”, “Ciao”); E2 = E3 = E1; – What should it do? 1. Deallocate the memory used by E2 2. Allocate new memory 3. Copy data from E1 to E2 Lec 5 Programming in C++ 11

Assignment Operator

Employee& Employee::operator=( const Employee& E) { //Deallocate the memory delete [] firstName; delete [] lastName;

//Allocate new memory and perform the copy firstName = new char[strlen( E.firstName ) + 1]; strcpy( firstName, E.firstName );

lastName = new char[strlen( E.lastName ) + 1]; strcpy( lastName, E.lastName );

return *this; } See copy constructor

Lec 5 Programming in C++ 12

6 Self-assignment

•What if Employee E1(“Anna”,“Pettersson”); E1 = E1; • Does the code in the slide before work? – NO!! Why? •First, test for self-assignment

Lec 5 Programming in C++ 13

Assignment Operator

Employee& Employee::operator=( const Employee& E) { if (&E != this){// test for self-assignment //Deallocate the memory delete [] firstName; delete [] lastName;

//Allocate new memory and perform the copy firstName = new char[strlen( E.firstName ) + 1]; strcpy( firstName, E.firstName );

lastName = new char[strlen( E.lastName ) + 1]; strcpy( lastName, E.lastName ); } return *this; }

Lec 5 Programming in C++ 14

7 Copy constructor and Assignment operator •A copy constructor, destructor, and assignment operator are usually provided for classes that allocate memory dynamically. •Differences between copy constructor and assignment operator? • Homework: – How to prevent an Employee object to be assigned to another Employee (e.g. E1 = E2; )?

Lec 5 Programming in C++ 15

Recursive Data Structures

• List of integers

41012

header Empty List Node 10 next header = new Node(0, NULL); value header

Lec 5 Programming in C++ 16

8 Node.h class Node { public: // Constructor Node (int val, Node* n = NULL);

private: int value; Node* next;

friend class List; };

Lec 5 Programming in C++ 17

List.h class List { public: List (); List (int a[], int n); List (const List& b); //copy constructor ~List (); //destructor

bool empty() const; int cardinality() const; bool member(int x) const;

void insert(int x); void remove(int x); ... private: Node *header; friend std::ostream& operator<< (std::ostream& os, const List& b); }; Lec 5 Programming in C++ 18

9 Insert a Value in a Sorted List

temp

41012

header 6

ptr 1. ptr = new Node(6); 2. ptr→next = temp→next;

3. temp→next = ptr;

Lec 5 Programming in C++ 19

Insert a Value in a Sorted List

Tests the end of the list void List::insert (int value) { Node *temp = header; while (temp -> next != 0 && temp -> next -> value < value) temp = temp -> next; if (temp -> next == 0 || temp -> next -> value != value) temp -> next = new Node(value, temp -> next); }

Avoids dereferencing a pointer to NULL (0) In C++, boolean operations (e.g. &&) use short-circuit evaluation

Lec 5 Programming in C++ 20

10