chapter 14 pointers, classes, lists, and virtual functions

100
CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

Upload: ariel-powers

Post on 26-Dec-2015

234 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

CHAPTER 14

POINTERS, CLASSES, LISTS, AND VIRTUAL

FUNCTIONS

Page 2: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

THE POINTER DATA TYPE AND POINTER VARIABLES

Pointer variable: A variable whose content is an address— (that is, a memory address).

Declaring Pointer Variables The general syntax of declaring a pointer variable is

dataType *identifier;

int *p;

char *ch;

Page 3: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

The statement

int *p;

is equivalent to the statement

int* p;

which is equivalent to the statement

int * p; The character * can appear anywhere between the data type name and the

variable name.

int* p, q; Only p is the pointer variable, not q. Here q is an int variable. To avoid confusion, we prefer to attach the character * to the variable

name.

int *p, q;

The following statement declares both p and q to be pointer variables of the type int.int *p, *q;

Page 4: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

THE ADDRESS OF OPERATOR (&) In C++, the ampersand, &, called the address of operator, is a unary

operator that returns the address of its operand.

Given the statements

int x;

int *p;

the statement

p = &x;

assigns the address of x to p. That is, x and the value of p refers to the same memory location.

Page 5: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

THE DEREFERENCING OPERATOR (*) C++ also uses * as a unary operator. When used as a unary operator, *, commonly referred to as the

dereferencing operator or indirection operator, refers to the object to which its operand (that is, a pointer) points

int x = 25;int *p;p = &x; //store the address of x in p

The statement

cout<<*p<<endl;

prints the value of x. Also the statement

*p = 55;

will store 55 in the memory location pointed to by p, that is, in x.

Page 6: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

int *p;int num;

• p is a pointer variable of the type int and num is a variable of type int.

Page 7: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

num = 78;

Page 8: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

p = &num;

Page 9: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

*p = 24;

Page 10: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

1. &p, p, and *p all have different meanings.

2. &p means the address of p—that is, 1200 (in Figure 14-4).

3. p means the content of p (1800 in Figure 14-4).

4. *p means the content (24 in Figure 14-4) of the memory location (1800 in Figure 14-4) pointed to by p (that is, pointed to by the content of memory location 1200).

Page 11: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

Example 14-1int *p;int x;

Page 12: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

• After the statement

x = 50;

Page 13: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

• After the statement: p = &x;

• After the statement

*p = 38;

Page 14: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

1. A declaration such as

int *p;

allocates memory for p only, not for *p.

2. Assume the following:

int *p;

int x;

a. p is a pointer variable;

b. Content of p only points to a memory location of the type int;

c. Memory location x exists and is of the type int.

The assignment

p = &x;

is legal. After the execution of this statement *p is valid and meaningful.

Page 15: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

Example 14-2//Chapter 14: Example 14-2

#include <iostream>

using namespace std;

int main(){ int *p; int x = 37;

cout<<"Line 1: x = "<<x<<endl; //Line 1

p = &x; //Line 2

cout<<"Line 3: *p = "<<*p <<", x = "<<x<<endl; //Line 3

*p = 58; //Line 4

cout<<"Line 5: *p = "<<*p <<", x = "<<x<<endl; //Line 5

cout<<"Line 6: Address of p = "<<&p<<endl; //Line 6

cout<<"Line 7: Value of p = "<<p<<endl; //Line 7

Page 16: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

cout<<"Line 8: Value of the memory location " <<"pointed to by *p = "<<*p<<endl; //Line 8

cout<<"Line 9: Address of x = "<<&x<<endl; //Line 9 cout<<"Line 10: Value of x = "<<x<<endl; //Line 10

return 0;}

Sample Run

Line 1: x = 37Line 3: *p = 37, x = 37Line 5: *p = 58, x = 58Line 6: Address of p = 006BFDF4Line 7: Value of p = 006BFDF0Line 8: Value of the memory location pointed to by *p = 58Line 9: Address of x = 006BFDF0Line 10: Value of x = 58

Page 17: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

CLASSES, STRUCTS, AND POINTER VARIABLES

You can also declare pointers to other data types, such as classes and structs.

struct studentType{ char name[26]; double gpa; int sID; char grade;};

studentType student;studentType *studentPtr;

studentPtr = &student;

Page 18: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

student.gpa = 3.9; (*studentPtr).gpa = 3.9;

store 3.9 in the component gpa of the object student.

Since dot has a higher precedence than the dereferencing operator, parentheses are important.

C++ provides another operator, called the member access operator arrow, ->.

The syntax for accessing a class (struct) member using the operator -> is

pointerVariableName->classMemberName

The following statements are equivalent.

(*studentPtr).gpa = 3.9; studentPtr->gpa = 3.9;

Page 19: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

Example 14-3class classExample{public: void setX(int a); void print() const;

private:int x;

};

void classExample::setX(int a){

x = a;}

void classExample::print() const{

cout<<"x = "<<x<<endl;}

Page 20: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

int main(){

classExample *cExpPtr; //Line 1classExample cExpObject; //Line 2

cExpPtr = &cExpObject; //Line 3

cExpPtr->setX(5); //Line 4cExpPtr->print(); //Line 5

return 0;}

Output

x = 5

Page 21: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

INITIALIZING POINTER VARIABLESBecause C++ does not automatically initialize variables, pointer variables must be initialized if you do not want to point to anything.

Pointer variables are initialized using the constant value 0, called the null pointer. You can also use the constant NULL.

p = NULL;

p = 0;

Page 22: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

DYNAMIC VARIABLES Variables that are created during program execution are called

dynamic variables. With the help of pointers, C++ creates dynamic variables. C++ provides two operators, new and delete, to create and destroy

dynamic variables, respectively. When a program requires a new variable, the operator new is used;

when a program no longer needs a dynamic variable, the operator delete is used.

In C++, new and delete are reserved words.

Page 23: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

The syntax to use the operator new is

new dataType; //to allocate a single variablenew dataType[intExp]; //to allocate an array of variables

where intExp is any expression evaluating to a positive integer. The operator new allocates memory (a variable) of the designated

type and returns a pointer to it—that is, the address of this allocated memory.

The allocated memory is uninitialized.

Page 24: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

int *p;char *q; int x;

• The statement

p = &x;

stores the address of x in p. No new memory is allocated. • The statement

p = new int;

creates a variable during execution somewhere in the memory, and stores the address of the allocated memory in p.

• The allocated memory is accessed via pointer dereferencing, *p. • The statement

q = new char[16];

creates an array of 16 components of the type char and stores the base address in q.

Page 25: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

int *p; //p is a pointer of the type int

char *name; //name is a pointer of the type char

string *str; //str is a pointer of the type string

p = new int;

*p = 28; //stores 28 in the allocated memory

name = new char[5];

strcpy(name, "John"); //stores John in name

str = new string; //allocates memory of the type string

//and stores the address of the

//allocated memory in str

*str = "Sunny Day"; //stores the string "Sunny Day" in

//memory pointed to by str

Page 26: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

The C++ operator delete is used to destroy dynamic variables. The syntax to use the operator delete has two forms:

delete pointer; //to destroy a single dynamic variabledelete [] pointer; //to destroy a dynamically created

//array

The statements

delete p; delete [] name;

deallocate memory referenced by the pointers p and name.

Page 27: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

OPERATIONS ON POINTER VARIABLES

Assignment Value of one pointer variable can be assigned to another

pointer variable of the same type. Relational operations

Two pointer variables of the same type can be compared for equality, and so on.

Some limited arithmetic operations. Integer values can be added and subtracted from a pointer

variable. Value of one pointer variable can be subtracted from another

pointer variable.

Page 28: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

int *p, *q;

The statement

p = q;

copies the value of q into p.

The expression

p == q

evaluates to true if both p and q have the same value.

The expression

p != q

evaluates to true, if both p and q point to different memory locations.

Page 29: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

Arithmetic operations, that are allowed, differ from the arithmetic operations on numbers.

int *p;double *q;char *chPtr;studentType *stdPtr; //studentType data type is

//as defined before

The memory allocated for an int variable is 4 bytes, a double variable is 8 bytes, and a char variable is 1 byte. The memory allocated for a variable of the type studentType is 39 bytes.

The statement

p++; or p = p+1;

increments the value of p by 4 bytes.

Page 30: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

The statements

q++;

chPtr++;

increment the value of q by 8 bytes and the value of chPtr by 1 byte

The statement

stdPtr++;

increments the value of stdPtr by 39 bytes. The statement

p = p + 2;

increments the value of p by 8 bytes.

Page 31: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

When an integer is added to a pointer variable, the value of the pointer variable is incremented by the integer times the size of the memory that the pointer is pointing to.

When an integer is subtracted from a pointer variable, the value of the pointer variable is decremented by the integer times the size of the memory to which the pointer is pointing.

Page 32: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

DYNAMIC ARRAYS An array created during the execution of a program is called a

dynamic array. To create a dynamic array, we use the second form of the new

operator. The statement

int *p;

declares p to be a pointer variable of the type int. The statement

p = new int[10];

allocates 10 contiguous memory locations, each of the type int, and stores the address of the first memory location into p.

Page 33: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

The statement

*p = 25;

stores 25 into the first memory location.

p++;*p = 35;

stores 35 into the second memory location.

C++ allows us to use array notation to access these memory locations.

p[0] = 25;p[1] = 35;

for(j = 0; j < 10; j++) p[j] = 0;

Page 34: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

int list[10];

list is a pointer variable. We always want list to point to the first array component. Any attempt to use increment or decrement operation on list will

result in compile time error. If p is a pointer variable of the type int, then the statement

p = list;

copies the value of list into p. We are allowed to perform increment and decrement operations on p.

An array name is a constant pointer.

Page 35: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

Example 14-4

int *intList; //Line 1int arraySize; //Line 2

cout<<"Enter array size: ";//Line 3cin>>arraySize; //Line 4cout<<endl; //Line 5

intList = new int[arraySize]; //Line 6

The statement at Line 1 declares intList to be a pointer of the type int The statement at Line 2 declares arraySize to be an int variable. The statement at Line 3 prompts the user to enter the size of the array. The statement at Line 4 inputs the array size into the variable arraySize. The statement at Line 6 creates an array of the size specified by arraySize, and the base address of the array is stored in intList.

From this point on, you can treat intList just like any other array. For example, you can use the array notation to process the elements of intList and pass intList as a parameter to the function.

Page 36: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

Functions and Pointers A pointer variable can be passed as a parameter to a function either by

value or by reference.

In C++, to make a pointer a reference parameter in a function heading, * appears before the & between the data type name and the identifier.

void example(int* &p, double *q)

{

.

.

.

}

Both p and q are pointers. The parameter p is a reference parameter; the parameter q is a value parameter.

Page 37: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

Pointers and Function Return Value In C++, a function can return a value of the type pointer.

The return type of the function

int* testExp(...)

{

.

.

.

}

is a pointer of the type int.

Page 38: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

SHALLOW VERSUS DEEP COPY AND POINTERSint *p;

p = new int;

The first statement declares p to be a pointer variable of the type int. The second statement allocates memory of the type int, and the address of the

allocated memory is stored in.

Page 39: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

*p = 87;

int *first;int *second;

first = new int[10];

Page 40: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

second = first; //Line ***

Page 41: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

delete [] second;

In a shallow copy, two or more pointers of the same type point to the same memory; that is, they point to the same data.

Page 42: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

second = new int[10];

for(int j = 0; j < 10; j++) second[j] = first[j];

• In a deep copy, two or more pointers have their own data.

Page 43: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

CLASSES AND POINTERS: SOME PECULIARITIESclass pointerDataClass{public: ...

private: int x; int lenP; int *p;};

pointerDataClass objectOne;pointerDataClass objectTwo;

Page 44: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

The Destructor The object objectOne has a pointer data member p. Suppose that during program execution the pointer p creates a dynamic array. When objectOne goes out of scope, all data members of objectOne are

destroyed. However, p created a dynamic array, and dynamic memory must be

deallocated using the operator delete. If the pointer p does not use the delete operator to deallocate the dynamic

array, the memory space of the dynamic array would stay marked as allocated, even though no one can access it.

How do we ensure that when p is destroyed, the dynamic memory created by p is also destroyed?

Page 45: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

If a class has a destructor, the destructor automatically executes whenever a class object goes out of scope.

We can put the necessary code in the destructor to ensure that when objectOne goes out of scope, the memory created by the pointer p is deallocated.

pointerDataClass::~pointerDataClass(){delete [] p;

}

class pointerDataClass{public: ~pointerDataClass();...

private: int x; int lenP; int *p;};

Page 46: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

The Assignment Operator

Page 47: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

objectTwo = objectOne;

If objectTwo.p deallocates the memory space to which it points, objectOne.p would become invalid.

Page 48: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

To avoid this shallow copying of data for classes with a pointer data member, C++ allows the programmer to extend the definition of the assignment operator.

This process is called overloading the assignment operator. Chapter 15 explains how to accomplish this task by using operator

overloading. Once the assignment operator is properly overloaded, both the objects objectOne and objectTwo have their own data, as shown in Figure 14-19.

Page 49: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

The Copy Constructor Consider the following statement:

pointerDataClass objectThree(objectOne);

The object objectThree is being declared and is also being initialized by using the value of objectOne.

This initialization is called the default member-wise initialization. The default member-wise initialization is due to the constructor, called

the copy constructor (provided by the compiler.) This default initialization would lead to a shallow copying of the data.

Page 50: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

void destroyList(pointerDataClass paramObject);

destroyList(objectOne);

Page 51: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

• Because objectOne is passed by value, the data members of paramObject should have their own copy of the data. In particular, paramObject.p should have its own memory space.

• How do we ensure that this is , in fact, the case?

Page 52: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

If a class has pointer data members:

During object declaration, the initialization of one object using the value of another object would lead to shallow copying of data if the default member-wise copying of data is allowed.

If, as a parameter, an object is passed by value and the default member-wise copying of data is allowed, it would lead to shallow copying of data.

In both cases, to force each object to have its own copy of the data, we must override the definition of the copy constructor provided by the compiler.

This is usually done by putting a statement that includes the copy constructor in the definition of the class, and then writing the definition of the copy constructor.

For the class pointerDataClass, we can overcome this shallow copying of data problem by including the copy constructor in the class pointerDataClass.

Page 53: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

The copy constructor automatically executes in two situations (as described in the previous list): When an object is declared and initialized by using the value of another

object When, as a parameter, an object is passed by value

Once the copy constructor is properly defined for the class pointerDataClass, both objectOne.p and objectThree.p will have their own copies of the data. Similarly, objectOne.p and paramObject.p will have their own copies of the data.

Page 54: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

• The general syntax to include the copy constructor in the definition of a class is

className (const classname& otherObject);

Page 55: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

Example 14-5

class pointerDataClass{public: void print() const; void setData(); void destroyP(); pointerDataClass(int sizeP = 10); ~pointerDataClass();

pointerDataClass (const pointerDataClass& otherObject); //the copy constructor

private: int x; int lenP; int *p; //pointer to an int array};

Page 56: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

void pointerDataClass::print() const{cout<<"x = "<<x<<endl;

cout<<"p = ";

for(int i = 0; i < lenP; i++) cout<<p[i]<<" ";cout<<endl;

}

void pointerDataClass::setData(){cout<<"Enter an integer for x: ";cin>>x;cout<<endl;

cout<<"Enter "<<lenP<<" numbers: ";

for(int i = 0; i < lenP; i++) cin>>p[i];

cout<<endl;}

Page 57: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

void pointerDataClass::destroyP(){lenP = 0;delete [] p;p = NULL;

}

pointerDataClass::pointerDataClass(int sizeP){x = 0;

if(sizeP <= 0){

cout<<"Array size must be positive"<<endl;cout<<"Creating an array of size 10"<<endl;

lenP = 10;}else

lenP = sizeP;

p = new int[lenP];}

Page 58: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

pointerDataClass::~pointerDataClass(){delete [] p;

}

//copy constructorpointerDataClass::pointerDataClass (const pointerDataClass& otherObject){

x = otherObject.x;

lenP = otherObject.lenP; p = new int[lenP];

for(int i = 0; i < lenP; i++) p[i] = otherObject.p[i];

}

Page 59: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

#include <iostream>#include "ptrDataClass.h"

using namespace std;

void testCopyConst(pointerDataClass temp);

int main(){pointerDataClass one(5); //Line 1

one.setData(); //Line 2cout<<"Line 3: ###Object one's data###"<<endl; //Line 3one.print(); //Line 4cout<<"Line 5:______________________________"

<<"______________"<<endl; //Line 5

pointerDataClass two(one); //Line 6

cout<<"Line 7: ^^^Object two's data^^^"<<endl; //Line 7two.print(); //Line 8cout<<"Line 9:_______________________________" <<"_____________"<<endl; //Line 9

two.destroyP(); //Line 10

cout<<"Line 11: ~~~ Object one's data after " <<"destroying object two.p ~~~"<<endl; //Line 11

Page 60: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

one.print(); //Line 12cout<<"Line 13:_______________________________" <<"_____________"<<endl; //Line 13

cout<<"Line 14: Calling the function testCopyConst" <<endl; //Line 14

testCopyConst(one); //Line 15

cout<<"Line 16:_______________________________" <<"_____________"<<endl; //Line 16

cout<<"Line 17: After a call to the function " <<"testCopyConst, object one is:"<<endl; //Line 17

one.print(); //Line 18

return 0; //Line 19

}

Page 61: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

void testCopyConst(pointerDataClass temp){cout<<"Line 20: *** Inside function " <<"testCopyConst ***"<<endl; //Line 20

cout<<"Line 21: Object temp data:"<<endl; //Line 21temp.print(); //Line 22

temp.setData(); //Line 23cout<<"Line 24: After changing the object " <<"temp, its data is: "<<endl; //Line 24temp.print(); //Line 25

cout<<"Line 26: *** Exiting function " <<"testCopyConst ***"<<endl; //Line 26

}

Page 62: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

Sample Run: In this sample run, the user input is in red.Enter an integer for x: 28

Enter 5 numbers: 2 4 6 8 10

Line 3: ###Object one's data###x = 28p = 2 4 6 8 10Line 5:____________________________________________Line 7: ^^^Object two's data^^^x = 28p = 2 4 6 8 10Line 9:____________________________________________Line 11: ~~~ Object one's data after destroying object two.p ~~~

x = 28p = 2 4 6 8 10Line 13:____________________________________________Line 14: Calling the function testCopyConstLine 20: *** Inside function testCopyConst ***Line 21: Object temp data:x = 28p = 2 4 6 8 10

Page 63: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

Enter an integer for x: 65

Enter 5 numbers: 1 3 5 7 9

Line 24: After changing the object temp, its data is:x = 65p = 1 3 5 7 9Line 26: *** Exiting function testCopyConst ***Line 16:____________________________________________Line 17: After a call to the function testCopyConst, object one is:

x = 28p = 2 4 6 8 10

Page 64: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

Array-Based Lists

List: A collection of elements of the same type. The length of a list is the number of elements in the list.

Operations performed on a list are:

1. Create the list. The list is initialized to an empty state.

2. Determine whether the list is empty.

3. Determine whether the list is full.

4. Find the size of the list.

5. Destroy, or clear the list.

Page 65: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

Operations performed on a list are:

6. Determine whether an item is the same as a given list

element.

7. Insert an item in the list at the specified location.

8. Remove an item from the list at the specified location.

9. Replace an item at the specified location with another

item.

10.Retrieve an item from the list at the specified location.

11.Search the list for a given item.

Page 66: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

Lists are stored as an array. The size of the array can be specified when a list object is declared.

To maintain and process the list in an array, we need three variables:

• The array holding the list elements• A variable to store the length of the list (that is, the number of

elements currently in the array)• A variable to store the size of the array (that is, the maximum

number of elements that can be stored in the array)

Page 67: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

• List Class definitionclass arrayListType{

bool isEmpty();// Returns true if the list is empty// otherwise, returns false.

bool isFull();// Returns true if the list is full// otherwise, returns false.

int listSize();// Returns the size of the list, that is, the

number// of elements currently in the list.

int maxListSize();//Returns the maximum size of the list, that is,

the//maximum number of elements that can be stored in //the list.

void print() const;//Outputs the elements of the list

bool isItemAtEqual(int location, int item);//If the item is the same as the list element at

the//position specified by the location, returns true;//otherwise, returns false.

Page 68: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

• List Class definition

void insertAt(int location, int insertItem);//Inserts an item in the list at he specified location.//The item to be inserted and the location are passed//as parameters to the function//If the list is full or the location is out of range,//an appropriate message is displayed.

void insertEnd(int insertItem);//Inserts an item at the end of the list. The item to//be inserted is specified by the parameter insertItem.

void removeAt(int location);//Removes the item from the list at the specified//position. The location of the item to be removed is//passed as a parameter to this function.

void retrieveAt(int location, int& retItem);//Retrieves the element from the list at the position//specified by the location. The item is returned via//the parameter retItem.

void replaceAt(int location, int repItem);//Replaces the element in the list at the position//specified by the location. The item to be replaced is//specified by the parameter repItem.//If the list is full, an appropriate message is

displayed

Page 69: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

• List Class definition

void clearList();//All elements from the list are removed. After this//operation, the size of the list is zero.

int seqSearch(int item);//Searches the list for a given item. If the item is //found, returns the location in the array where the//item is found; otherwise, returns -1

void insert(int insertItem);//The item specified by the parameter insertItem is//inserted at the end of the list. However, the list//is first searched to see whether the item to be //inserted is already in the list. If the item is//already in the list, an appropriate message is

output.void remove(int removeItem);

//Removes an item from the list. The item to be removed

//is specified by the parameter removeItem.arrayListType(int size = 100);

//constructor//Creates an array of the size specified by the

//parameter size. The default array size is 100.

Page 70: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

• List Class definition

arrayListType(const arrayListType& otherList);//copy constructor

-arrayListType();//destructor//Deallocates the memory occupied by the array

protected:int *list; //array to hold the list elementsint length; //stores the length of the list

int maxSize; //stores the maximum size of the list

};

Page 71: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

• Data member length stores the number of elements currently in the list• Data member maxSize specifies the maximum size of the list• The list is empty if length is zero and full if length is equal to maxSize

Therefore definition of functions isEmpty, isFull, listSize and maxListSize are:

bool arrayListType::isEmpty(){

return(length ==0);}

bool arrayListType::isFull(){

return(length ==maxSize);}

int arrrayListType::listSize(){

return length;}

int arrrayListType::maxListSize(){

return maxSize;}

Page 72: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

• The function print outputs the elements of the list.

void arrayListType::print()const{

int i;

for( i = 0; i < length; i++ )cout<<list[i]<<“ “;

cout<<endl;}

• The definition of function isItemEqual

bool arrayListType::isItemEqual(int location, int item){

return(list[location] == item);}

Page 73: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

• The function insertAt inserts an item at a specific location

void arrayListType::insertAt(int location, int insertItem){

int i;

if( location < 0 || location >= maxSize)cout<<“The position of the item to be inserted “ <<“is out of range”<<endl;

elseif(length>=maxSize) // list is full cout<<“Cannot insert in a full list”<<endl;else{ for( i = length; i > location; i-- ) list[i] = list[i-1];//move elements down

list[location] = insertItem; //inserts the item at the

//specified position

length++; //increment the length}

}//end insertAt

Page 74: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

• The function insertEnd inserts an item at the end of the array

void arrayListType::insertEnd(int insertItem){

if(length >= maxSize) // list is full cout<<“Cannot insert in a full list”<<endl;

else{ list[length] = insertItem; //inserts the item at the end

length++; //increment the length}//end insertEnd

• The function removeAt removes an item from a specific location in the list.

• The location of the item to be removed is passed as a parameter.• After the item is removed the list is reduced by 1.

Page 75: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

The function removeAtvoid arrayListType::removeAt(int location){

int i;if( location < 0 || location >= maxSize)

cout<<“The location of the item to be removed “ <<“is out of range”<<endl;

else{

for( i = location; i < length; i++ ) list[i] = list[i+1];

length--;}

}

• The function retrieveAtvoid arrayListType::retrieveAt(int location, int& retItem){

if( location < 0 || location >= length)cout<<“The location of the item to be retrieved is“ <<“is out of range”<<endl;

elseretItem = list[location];

}

Page 76: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

• The function replaceAt

void arrayListType::replaceAt(int location, int& retItem){

if( location < 0 || location >= length)cout<<“The location of the item to be replaced is“ <<“is out of range”<<endl;

elselist[location] = repItem;

}

• The function clearList, removes the elements from the list, leaving it empty

• This is accomplished by setting data member length to zero

void arrayListType::clearList(){

length = 0;}

Page 77: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

• The constructor creates an array of the size specified by the user, and initializes the length of the list to zero and maxSize to the size specified by the user.

arrayListType:: arrayListType(int size){

if( size < 0){

cout<<“The array size must be positive. Creating “ <<“an array of size 100. ”<<endl;maxSize = 100;

}else

maxSize = size;

length = 0;list = new int[maxSize];

}

• The destructor arrayListType::~arrayListType(){

delete []list;}

Page 78: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

• The copy constructor is called when an object is passed as a (value) parameter to a function and when an object is declared and initialized using the value of another object of the same type.

arrayListType::arrayListType(const arrayListType& otherList)

{int j;

maxSize = otherList.maxSize;length = otherList.length;list = new int[maxSize];

if( length != 0)for(j=0; j<length; j++); list[j] = otherList[j];

}

Page 79: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

• The function seqSearch is a linear or sequential search• The function seqSearch searches the list for a given item

int arrayListType::seqSearch(int item){

int loc;bool found = false;

for(loc=0; loc<length; loc++); if(list[loc] == item){

found = true;break;

}

if(found)return loc;

elsereturn –1;

}

Page 80: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

• The insert function inserts a new item in the list. • Call function seqSearch to search for duplicates

void arrayListType::insert(int insertItem){

int loc;

if(length == 0)list[length++] = insertItem;

else if(length == maxSize)

cout<<“Cannot insert in a full list.”<<endl; else

{ loc = seqSearch(insertItem); if( loc == -1)//The item to be inserted

//does not exist in the list list[length++] = insertItem; else cout<<“the item to be inserted is already in

“ <<“the list. No duplicates are

allowed.”<<endl;}

}

Page 81: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

• The remove function deletes an item from the list. • Call function seqSearch to determine if the item is in the list

void arrayListType::remove(int removeItem){

int loc;

if(length == 0)cout<<“Cannot delete from an empty list”<<endl;

else{

loc = seqSearch(removeItem);

if(loc != -1) removeAt(loc);

else cout<<“the item to be deleted is not in the

list.“ <<endl;

}}

Page 82: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

• The following is the result of the sample run of the test program on page 711

Sample Run: In this sample run, the user input is shaded

Line 3: Enter numbers ending with –99923 16 15 25 35 46 14 32 98 7 –999

Line 8: The list you entered is:23 16 15 25 35 46 14 32 98 7Line 10: The list size is: 10Line 11: Enter the item to be deleted: 98

Line 15: After removing 98 the list is:23 16 15 25 35 46 14 32 7Line 16: The list size is: 9Line 23: Inside the function testCopyConstructor.23 16 15 25 35 46 14 32 7Line 25: The list size is: 9Line 19: The list after the copy constructor.23 16 15 25 35 46 14 32 7Line 21: The list size is: 9

Page 83: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

INHERITANCE, POINTERS, AND VIRTUAL FUNCTIONS

C++ allows the user to pass an object of a derived class to a formal parameter of the base class type.

class baseClass{public: void print(); baseClass(int u = 0);private: int x;};

class derivedClass: public baseClass{public: void print(); derivedClass(int u = 0, int v = 0);private: int a;};

Page 84: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

void baseClass::print() {

cout<<"In baseClass x = "<<x<<endl;}

baseClass::baseClass(int u){

x = u;}

void derivedClass::print() {

cout<<"In derivedClass ***: ";baseClass::print();cout<<"In derivedClass a = "<<a<<endl;

}

derivedClass::derivedClass(int u, int v) : baseClass(u){

a = v;}

Page 85: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

void callPrint(baseClass& p){

p.print();}

int main(){ baseClass one(5); //Line 1 derivedClass two(3, 15); //Line 2

one.print(); //Line 3 two.print(); //Line 4

cout<<"*** Calling the function callPrint ***" <<endl; //Line 5

callPrint(one); //Line 6 callPrint(two); //Line 7

return 0;}

Page 86: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

Output

In baseClass x = 5In derivedClass ***: In baseClass x = 3In derivedClass a = 15*** Calling the function callPrint ***In baseClass x = 5In baseClass x = 3

Page 87: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

In compile-time binding, the necessary code to call a specific function is generated by the compiler.

Compile-time binding is also known as static binding. For the statement in Line 7, the actual parameter is of the type derivedClass.

When the body of the function two executes, logically the print function of object two should execute, which is not the case.

C++ corrects this problem by providing the mechanism of virtual functions.

The binding of virtual functions occurs at program execution time, not at compile-time.

This kind of binding is called run-time binding. In run-time binding, the compiler does not generate code to call a

specific function; instead, it generates enough information to enable the run-time system to generate the specific code for the appropriate function call.

Run-time binding is also known as dynamic binding.

Page 88: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

virtual function• A virtual function is a function member of a

class, declared using the "virtual" keyword. A pointer to a derived class object may be assigned to a base class pointer, and a virtual function called through the pointer. If the function is virtual and occurs both in the base class and in derived classes, then the right function will be picked up based on what the base class pointer "really" points at.

Page 89: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

class baseClass{public: virtual void print(); //virtual function baseClass(int u = 0);

private: int x;};

class derivedClass: public baseClass{public: void print(); derivedClass(int u = 0, int v = 0);

private: int a;};

Page 90: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

If we execute the previous program with these modifications, the output is as follows.

Output

In baseClass x = 5

In derivedClass ***: In baseClass x = 3

In derivedClass a = 15

*** Calling the function callPrint ***

In baseClass x = 5

In derivedClass ***: In baseClass x = 3

In derivedClass a = 15

Page 91: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

//Chapter 14: Virtual Functions

#include <iostream>

#include "classExtTestVirtual.h"

using namespace std;

void callPrint(baseClass *p);

int main(){ baseClass *q; //Line 1 derivedClass *r; //Line 2

q = new baseClass(5); //Line 3 r = new derivedClass(3,15); //Line 4

q->print(); //Line 5 r->print(); //Line 6

cout<<"*** Calling the function callPrint ***" <<endl; //Line 7 callPrint(q); //Line 8 callPrint(r); //Line 9

return 0;}

Page 92: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

void callPrint(baseClass *p){

p->print();}

Output

In baseClass x = 5In derivedClass ***: In baseClass x = 3In derivedClass a = 15*** Calling the function callPrint ***In baseClass x = 5In derivedClass ***: In baseClass x = 3In derivedClass a = 15

Page 93: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

//Chapter 14: Virtual Functions and value parameters

#include <iostream>

#include "classExtTestVirtual.h"

using namespace std;

void callPrint(baseClass p);

int main(){ baseClass one(5); //Line 1 derivedClass two(3, 15); //Line 2

one.print(); //Line 3 two.print(); //Line 4

cout<<"*** Calling the function callPrint ***" <<endl; //Line 5

callPrint(one); //Line 6 callPrint(two); //Line 7

return 0;}

Page 94: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

void callPrint(baseClass p) //p is a value parameter{

p.print();}

Output

In baseClass x = 5In derivedClass ***: In baseClass x = 3In derivedClass a = 15*** Calling the function callPrint ***In baseClass x = 5In baseClass x = 3

If a base class contains virtual functions, make the destructor of the base class virtual.

Page 95: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

THE ADDRESS OF OPERATOR AND CLASSES The address of operator is also used to create aliases to an object.

Consider the following statements:

int x;

int &y = x;

Both x and y refer to the same memory location. y is like a constant pointer variable. The statement

y = 25;

sets the value of y and hence of x to 25. Similarly the statement

x = 2 * x + 30;

updates the value of x and hence of y.

Page 96: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

The address of operator, &, can also be used to return the address of private data members of a class. However, if we are not careful this can result in serious errors in the program.

//header file testadd.h#ifndef H_testAdd#define H_testAdd

class testAddress{public: void setX(int); void printX() const; int& addressOfX(); //this function returns the //address of the private data member

private: int x;};

#endif

Page 97: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

//Implementation file testAdd.cpp#include <iostream>#include "testAdd.h"using namespace std;

void testAddress::setX(int inX){

x = inX;}

void testAddress::printX() const{

cout<<x;}

int& testAddress::addressOfX(){ return x;

}

Page 98: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

//Test program#include <iostream>#include "testAdd.h"using namespace std;

int main(){

testAddress a;int &y = a.addressOfX();

a.setX(50);cout<<"x in class testAddress = ";a.printX();cout<<endl;

y = 25;cout<<"After y = 25, x in class testAddress = ";a.printX();cout<<endl;

return 0;}

Outputx in class testAddress = 50After y = 25, x in class testAddress = 25

Page 99: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

#ifndef H_testAdd#define H_testAdd

class testAddress{public: void setX(int); void printX() const; const int& addressOfX(); //this function returns the //address of the private data //memberprivate: int x;};#endif

const int& testAddress::addressOfX(){ return x;

}

Page 100: CHAPTER 14 POINTERS, CLASSES, LISTS, AND VIRTUAL FUNCTIONS

The definition of the function addressOfX in the implementation file is:

const int& testAddress::addressOfX()

{

return x;

}

The same program now will generate compile-time errors.