View
221
Download
2
Embed Size (px)
Citation preview
1expanded by J. Goetz
Nell Dale
Chapter 6
Lists Plus
Slides by Sylvia Sorkin, Community College of Baltimore County - Essex Campus
C++ Plus Data Structures
expanded by J. Goetz
ADT Sorted List OperationsTransformers
– MakeEmpty – InsertItem – DeleteItem
Observers – IsFull– LengthIs
– RetrieveItem
Iterators – ResetList – GetNextItem
change state
observe state
process all
3expanded by J. Goetz
class SortedType<char>
MakeEmpty
~SortedType
DeleteItem . . .
InsertItem
SortedType
RetrieveItem
GetNextItem
‘C’ ‘L’ ‘X’
Private data:
length 3
listData
currentPos
3
4expanded by J. Goetz
What is a Circular Linked List?A circular linked list is a list in which every node has a successor; the “last” element is succeeded by the “first” element. •In the linear linked list we have to have a pointer to the beginning to access all nodes.
Here we can start at any node in the list and traverse the whole list
‘B’ ‘C’ ‘L’ ‘T’ ‘V’ ‘Y’
listData
5expanded by J. Goetz
Circular Linked List
• listData points to the last item in the list, so we have access to the first and the last node:
listData->info refers to the last node
listData->next->info refers to the first node
• The pointer never becomes NULL. So we never stop when the traversing pointer becomes NULL.
• Are good for applications that require access to both ends of the list. Implementation is not shorter or simpler.
6expanded by J. Goetz
// File: Circle.cpp// This file contains the member functions for the Circular Linked List// list coded in Chapter 6.1 of the text. // There is no need to change any of the declaration in class SortedType#include <cstdlib> template <class ItemType>struct NodeType{ ItemType info; NodeType* next; }; template <class ItemType>class SortedType{public: // constructors // void InsertItem(ItemType item); void DeleteItem(ItemType);…….. // other members go here
private: NodeType<ItemType>* listData; int length;};
7expanded by J. Goetz
template<class ItemType> // similar to RetrieveItem for Linear Linked List SortedTypevoid FindItem(NodeType<ItemType>* listData, ItemType item, NodeType<ItemType>*& location, NodeType<ItemType>*& predLoc, bool& found) //helper function, hidden within implementation p.339// Assumption: ItemType is a type for which the operators ''<'' and "==" are defined as either an appropriate built-in type or a
class that overloads these operations.// Pre: List is not empty.// Post:If there is an element someItem whose key matches item's key, then found = true; otherwise, found = false.// If found, location contains the address of someItem and predLoc contains the address of someItem's predecessor;// otherwise, location contains the address of item's logical successor and predLoc contains the address of item's logical
predecessor.{ // A. Set values bool moreToSearch = true; location = listData->next; // in the Linear Linked List SortedType was: location = listData; predLoc = listData; //(1) in the Linear Linked List SortedType was: predLoc = NULL; found = false;// B. Find the place while (moreToSearch && !found) { if (item < location->info) moreToSearch = false; //exit3: we have passed the location where item belongs (see Post: description), //exit right away if the item SMALLEST than any in the list, then predLoc = listData from (1) else if (item == location->info) found = true; //exit2: item is FOUND, if only ONE element was: predLoc = listData from (1) else { // move running pointers predLoc = location; location = location->next; moreToSearch = (location != listData->next); //exit1: it can be location = listData->next; (it was location != NULL for
//Linear Linked List SortedType ) so the first element again, item is NOT FOUND } }}
8expanded by J. Goetz
template<class ItemType> // concept is similar to InsertItem for Linear Linked List SortedTypevoid SortedType<ItemType>::InsertItem(ItemType item) // Circular Linked List p.340{ NodeType<ItemType>* newNode; NodeType<ItemType>* predLoc; NodeType<ItemType>* location; bool found; // A. Set values: allocate space and store item newNode = new NodeType<ItemType>; newNode->info = item; // B. store item //C. Find the place where the new element belongs if (listData != NULL) { FindItem(listData, item, location, predLoc, found); // D. Put the new element into the list using predLoc received from FindItem() newNode->next = predLoc->next; //(1) // case a: GENERAL – link new node with the next one predLoc->next = newNode; //(2) link new node with the previous one if (listData->info < item) // case d: General+ . If this is the last node (the LARGEST ELEM) in the
list. listData = newNode; //(3) reassign listData } // note: general case covers case c: inserting to front of the list-the SMALLEST one; see exit 1, 2 else // E. // case b: Inserting into an EMPTY list. { listData = newNode; // make listData point to the new node newNode->next = newNode; // make the new node point itself } length++;}
9expanded by J. Goetz
template<class ItemType> //Circular Linked Listvoid SortedType<ItemType>::DeleteItem(ItemType item) // concept is similar to Linear Linked List
SortedType//p.342{ NodeType<ItemType>* location; NodeType<ItemType>* predLoc; bool found; // A. Find FindItem(listData, item, location, predLoc, found); // B. Remove element from the list at location found in FindItem() if (predLoc == location) // check on return from FindItem listData = NULL; //case c: Only ONE node in list else { predLoc->next = location->next; // case a: GENERAL - jump over the node we are deleting // note: general case covers case b: inserting to front of the list-the SMALLEST one; see
exit3 in FindItem if (location == listData) // check on return from FindItem - General+ case listData = predLoc; //case d: Deleting last node in list – the LARGEST item } // C. Deallocate location delete location; length--;}
10expanded by J. Goetz
‘A’ ‘C’ ‘F’ ‘T’ ‘Z’
What is a Doubly Linked List?
listData
A doubly linked list is a list in which each node is linked to both its successor and its predecessor. In a circular linked list we cannot access its predecessors and cannot traverse in reverse, a doubly linked list allows the user to print the list in the ascending and descending order.
11expanded by J. Goetz
Each node contains two pointers template< class ItemType >struct NodeType {
ItemType info; // Data member
NodeType<ItemType>* back; // Pointer to predecessor NodeType<ItemType>* next; // Pointer to successor
};
. back . info . next
3000 ‘A’ NULL
12expanded by J. Goetz
template<class ItemType> // similar to FindItem for Circular Linked List SortedType – see removal of predLocvoid FindItem(NodeType<ItemType>* listData, ItemType item, NodeType<ItemType>*& location, bool& found) //helper
function, hidden within implementation p.345// Assumption: ItemType is a type for which the operators ''<'' and "==" are defined as either an appropriate built-in
type or a class that overloads these operations.// Pre: List is not empty.// Post:If there is an element someItem whose key matches item's key, then found = true; otherwise, found = false.// If found, location contains the address of someItem;// otherwise, location contains the address of item's logical successor { // A. Set values bool moreToSearch = true; location = listData; // location = listData->next; // in the Linear Linked List SortedType was: location = listData; //predLoc = listData; //(1) in the Linear Linked List SortedType was: predLoc = NULL; found = false;// B. Find the place while (moreToSearch && !found) { if (item < location->info) moreToSearch = false; //exit3: we have passed the location where item belongs (see Post: description), //exit right away if the item SMALLEST than any in the list, then predLoc = listData from (1) else if (item == location->info) found = true; //exit2: item is FOUND, if only ONE element was: predLoc = listData from (1) else { // move a pointer // predLoc = location; location = location->next; moreToSearch = (location != listData->next); //exit1: it can be location = listData->next; (it was location != NULL for
//Linear Linked List SortedType ) so the first element again, item is NOT FOUND
} }}
13expanded by J. Goetz
Doubly Linked List
• The algorithms for the insertion and deletion more complicated because there are more pointers to keep track.
14expanded by J. Goetz
Linking the New Node into the List
15expanded by J. Goetz
Deleting from a Doubly Linked List
16expanded by J. Goetz
What are Header and Trailer Nodes?
listData INT_MIN 5 8 13 INT_MAX
• A goal: simplify linked list by making sure that we never have end cases i.e. never insert or delete at the ends of the list
• A Header Node is a node at the beginning of a list that contains a key value smaller than any possible key.
• A Trailer Node is a node at the end of a list that contains a key larger than any possible key.
• Both header and trailer are placeholding nodes used to simplify list processing.
17expanded by J. Goetz
Recall Definition of Stack• Logical (or ADT) level: A stack is an ordered
group of homogeneous items (elements), in which the removal and addition of stack items can take place only at the top of the stack.
• A stack is a LIFO “last in, first out” structure.
expanded by J. Goetz
Stack ADT Operations• MakeEmpty -- Sets stack to an empty state.
• IsEmpty -- Determines whether the stack is currently empty.
• IsFull -- Determines whether the stack is currently full.
• Push (ItemType newItem) -- Adds newItem to the top of the stack.
• Pop () -- Removes the item at the top of the stack and returns it in item.
• Top (ItemType& item) -- Returns a copy of the top item
18
19expanded by J. Goetz
class StackType<int>
StackType
MakeEmpty
Pop and Top
Push
IsFull
IsEmpty Private data:
topPtr
~StackType
20 30
20expanded by J. Goetz
What happens . . .
• When a function is called that uses pass by value for a class object like our dynamically linked stack?
StackType
MakeEmpty
Pop; Top
Push
IsFull
IsEmpty Private data:
topPtr
~StackType
20 30
21expanded by J. Goetz
// FUNCTION CODEtemplate<class ItemType>void MyFunction( StackType<ItemType> SomeStack )
// SomeStack – formal parameter // Uses pass by value{
. .
.
.}
21
Passing a class object by value
22expanded by J. Goetz
Shallow Copy vs. Deep Copy
• A shallow copy copies only the class data members, and does not copy any pointed-to data.
• A deep copy copies not only the class data members, but also makes separately stored copies of any pointed-to data.
23expanded by J. Goetz
Pass by value makes a shallow copy
20 30
StackType<int> MyStack; // CLIENT CODE . . .
MyFunction( MyStack ); // function call
Private data: 7000 6000
topPtr 7000
Private data:
topPtr 7000
MyStack SomeStack (formal parameter)
shallow copy
24expanded by J. Goetz
What’s the difference?
• A shallow copy shares the pointed to data with the original class object.
• A deep copy stores its own copy of the pointed to data at different locations than the data in the original class object.
25expanded by J. Goetz
Making a deep copy
20 30
Private data: 7000 6000
topPtr 7000SomeStack (formal parameter)
20 30
Private data: 5000 2000
topPtr 5000
MyStack
deep copy
26expanded by J. Goetz
// FUNCTION CODEtemplate<class ItemType>void MyFunction( StackType<ItemType> SomeStack )
// Uses pass by value{
ItemType item;SomeStack.Pop();SomeStack.Top(item);
.
.
.
}
WHAT HAPPENS IN THE SHALLOW COPY SCENARIO?
26
Suppose MyFunction Uses Pop
27expanded by J. Goetz
MyStack.topPtr is left dangling
? 30
StackType<int> MyStack; // CLIENT CODE . . .
MyFunction( MyStack );
Private data:
topPtr 6000
MyStack SomeStack (formal parameter)
shallow copy
Private data: 7000 6000
topPtr 7000
28expanded by J. Goetz
MyStack.topPtr is left dangling
? 30
Private data:
topPtr 6000
MyStack SomeStack ( formal parameter)
shallow copy
Private data: 7000 6000
topPtr 7000
NOTICE THAT NOT JUST FOR THE SHALLOW COPY, BUT ALSO FOR ACTUAL PARAMETER MyStack,THE DYNAMIC DATA HAS CHANGED!
29expanded by J. Goetz
As a result . . .
• This default method used for pass by value is not the best way when a data member pointer points to dynamic data.
• Instead, you should write what is called a copy constructor, which makes a deep copy of the dynamic data in a different memory location.
30expanded by J. Goetz
More about copy constructors• When there is a copy constructor provided for a
class, the copy constructor is used to make copies for pass by value.
• You do not call the copy constructor.
• Like other constructors, it has no return type.
• Because the copy constructor properly defines pass by value for your class, it must use pass by reference in its definition.
31expanded by J. Goetz
Copy Constructor
• If a copy constructor is present, the default method of initialization (member by member copying) is inhibited. Instead, the copy-constructor is implicitly invoked whenever one class object is initialized by another
• Copy constructor is a special member function of a class that is implicitly called in these three situations:
1. passing object parameters by value,2. initializing an object variable in a declaration, 3. returning an object as the return value of a function.
32expanded by J. Goetz
// DYNAMICALLY LINKED IMPLEMENTATION OF STACK
template<class ItemType>class StackType {public:
StackType( ); // Default constructor.// POST: Stack is created and empty.
StackType( const StackType<ItemType>& anotherStack );// If a Copy constructor is present, the default method
of initialization (member by member copying) is inhibited. Instead, the copy-constructor is implicitly invoked whenever one class object is initialized by another
// Implicitly called for pass by value.. ..~StackType( );
// DESTRUCTOR is called automatically when the class // instance goes out of scope
// POST: Memory for nodes has been deallocated.private:
NodeType<ItemType>* topPtr ;}; 32
33expanded by J. Goetz
CLASS CONSTRUCTOR
CLASS COPY CONSTRUCTOR
CLASS DESTRUCTOR
DESTRUCTOR is called automatically when the class instance goes out of scope
Classes with Data Member Pointers Need
34expanded by J. Goetz
template<class ItemType> // COPY CONSTRUCTOR p.342
StackType<ItemType>:: // 2 running pointers ptr1 => ptr2
StackType( const StackType<ItemType>& anotherStack ) // copy anotherStack to self
{ NodeType<ItemType>* ptr1 ; //points to the node to be copied from(of anotherStack)
NodeType<ItemType>* ptr2 ; //points to the last node copied to the self stack
if ( anotherStack.topPtr == NULL )
topPtr = NULL ; //so empty self stack; topPtr a private data
else // allocate memory for the first node
{ topPtr = new NodeType<ItemType> ; //(1)allocate memory
topPtr->info = anotherStack.topPtr->info ; //(2)copy info
ptr1 = anotherStack.topPtr->next ; //(3)copy the first link pointer
ptr2 = topPtr ; //(4)ptr2 starts from topPtr
while ( ptr1 != NULL ) // deep copy other nodes
{ ptr2->next = new NodeType<ItemType> ; //(5) create a new next node
ptr2 = ptr2->next ; //(6) move ptr2 to the last of the self
ptr2->info = ptr1->info; //(7) copy info to the corresponding one
ptr1 = ptr1->next ; //(8) move ptr1 to the next one of anotherStack
}
ptr2->next = NULL ; //(9)while condition gives ptr1 = NULL so the self ends
}
}gtt534
35expanded by J. Goetz
// DYNAMICALLY LINKED IMPLEMENTATION OF STACK
template<class ItemType>class StackType {public:
StackType( ); // Default constructor.// POST: Stack is created and empty.
StackType( const StackType<ItemType>& anotherStack );// Copy constructor.
friend void copy (StackType<ItemType>, StackType<ItemType>&) //A friend function is not a member of the class, but it has permission to access private class members directly
.
.~StackType( );
// Destructor.// POST: Memory for nodes has been deallocated.
private:NodeType<ItemType>* topPtr ;
};
36expanded by J. Goetz
Copy routine is a friend of the class StackType so has access to private variables in the class
template<class ItemType> // COPY FUNCTION - copy anotherStack to mycopy object p.356//StackType<ItemType>:: Copy is no a member function, so 2 stacks should be passed //by parameters //2 running pointers ptr1 => ptr2void Copy (StackType<ItemType> anotherStack, StackType<ItemType>& mycopy)
{ NodeType<ItemType>* ptr1 ; //points to the node to be copied from(of anotherStack)NodeType<ItemType>* ptr2 ; //points to the last node copied to the mycopy stackif ( anotherStack.topPtr == NULL )
mycopy.topPtr = NULL //so empty mycopy stack; topPtr a private dataelse // allocate memory for the first node{ mycopy.topPtr = new NodeType<ItemType> ; //(1)allocate memory
mycopy.topPtr->info = anotherStack.topPtr->info ; //(2)copy infoptr1 = anotherStack.topPtr->next ; //(3)copy the first link pointer ptr2 = mycopy.topPtr ; //(4)ptr2 starts from topPtrwhile ( ptr1 != NULL ) // deep copy other nodes{ ptr2->next = new NodeType<ItemType> ; //(5) create a new next node ptr2 = ptr2->next ; //(6) move ptr2 to the last of the copy object ptr2->info = ptr1->info; //(7) copy info to the corresponding one ptr1 = ptr1->next ; //(8) move ptr1 to the next one of
anotherStack}ptr2->next = NULL ; //(9)while condition gives ptr1 = NULL so the mycopy
ends }
}
// almost identical to the copy constructor, the difference is marked by mycopy
37expanded by J. Goetz
What about the assignment operator?
• The default method used for assignment operator (=) of class objects makes a shallow copy.
• If your class has a data member pointer to dynamic data, you should write a member function to overload the assignment operator to make a deep copy of the dynamic data.
38expanded by J. Goetz
// DYNAMICALLY LINKED IMPLEMENTATION OF STACK template<class ItemType>class StackType {public:
StackType( ); // Default constructor.
StackType( const StackType<ItemType>& anotherStack );// Copy constructor.
void operator= ( StackType<ItemType> );// Overloads assignment operator.
. . .~StackType( ); // Destructor.
private:NodeType<ItemType>* topPtr ;
};// The function definition looks like thistemplate<class ItemType>void StackType<ItemType>::operator= (StackType<ItemType> anotherStack){//body}
38
expanded by J. Goetz
Using Overloaded Binary operator=
When a Member Function was defined
myStack = yourStack
myStack.operator=(yourStack)
When a Friend Function was defined
myStack = yourStack
operator=(myStack, yourStack)
39
40expanded by J. Goetz
C++ Operator Overloading Guides1 All operators except these :: . sizeof ?: may be
overloaded. 2 At least one operand must be a class instance.3 You cannot change precedence, operator symbols, or
number of operands.4 Overloading ++ and -- requires prefix form use by default,
unless special mechanism is used. 5 To overload these operators = ( ) [ ] member functions
(not friend functions) must be used. 6 An operator can be given multiple meanings if the data
types of operands differ.7 Many meanings for an operator can coexist as long as the
compiler can distinguish among the data types of the operands.
41expanded by J. Goetz
Using Overloaded Binary operator+
When a Member Function was defined
myStack + yourStack
myStack.operator+(yourStack)
When a Friend Function was defined
myStack + yourStack
operator+(myStack, yourStack)
42expanded by J. Goetz
Linked list in an Array of Recordes• Linked structures problems:
– Write a linked list to a file is meaningless on the next run time
– Dynamic allocation of each node is time expensive, specifically for the operating system code
• An array index remains valid on the next run of the program, so we can implement an array of nodes
43expanded by J. Goetz
A Sorted linked list stored in an Array of Nodes
44expanded by J. Goetz
A Sorted linked list Stored in an Array of Nodes
• Each node tells us the array index of the succeeding node
• See the chain of next indexes – following the links in the next member you can get the linked list
• the linked structure uses array indexes as “pointers”
• null is represented by no nodes[-1] exists or by NUL = -1
• no contain value elements in the list constitute free space
45expanded by J. Goetz
An Array with linked list of values and the list of free space
• Write own function to:– allocate nodes from the free
space – GetNode()
– delete nodes and return to the pool of free space – FreeNode()
• list, free are external pointers to the list of values and the list of free space, respectively
46expanded by J. Goetz
An Array with Three Lists (Including the Free List)
47expanded by J. Goetz
// file: ArrayLL.cpp p.366-7// This file contains the code for the array-of-records implementation// in the text. Incomplete definitions of ListType and NodeType and// one stub routine have been included to confirm that the syntax of// this code is correct. The student must write a complete definition// to use this code.typedef int ItemType;struct NodeType;
struct MemoryType{ int free; // index of the first free node NodeType* nodes; // a true pointer to the dynamically // allocated array of nodes
};// An incomplete definition of ListType sufficient to compile the code// in the array linked list implementationclass ListType{public: ListType(); ListType(int); ~ListType(); // Other member function prototypes go here. void MakeEmpty(); bool IsFull() const; int LengthIs() const; void RetrieveItem(ItemType& item, bool& found); void InsertItem(ItemType item); void DeleteItem(ItemType item); void ResetList(); void GetNextItem(ItemType& item);
private: int listData; int currentPos; int length; int maxItems; // new MemoryType storage; // new};
// Prototypes of auxiliary functions.void GetNode(int& nodeIndex, MemoryType& storage);// Returns the index of a free node in nodeIndex.
void FreeNode(int nodeIndex, MemoryType& storage);// Returns nodeIndex to storage.
void InitializeMemory(int maxItems, MemoryType&);// Initializes all memory to the free list.
// Define end-of-list symbol.const int NUL = -1;
struct NodeType{ int info; int next;};
// Definitions of the auxillary functions:void InitializeMemory(int maxItems, MemoryType&
storage){ for (int index = 1; index < maxItems; index++) storage.nodes[index-1].next = index;
storage.nodes[maxItems-1].next = NUL; storage.free = 0;}
48expanded by J. Goetz
void GetNode(int& nodeIndex, MemoryType& storage){ nodeIndex = storage.free; // take first free one
storage.free = storage.nodes[storage.free].next; // update free
}
void FreeNode(int nodeIndex, MemoryType& storage){ // take the nodeIndex received as a parameter and link it into the list of free nodes
storage.nodes[nodeIndex].next = storage.free; storage.free = nodeIndex; // put as a first one
}
49expanded by J. Goetz
//The class constructors for class ListType must allocate the storage//for the array of records and call InitializeMemory. For the default//constructor, we arbitrarily choose an array size of 500.
ListType::ListType(int max){ length = 0; maxItems = max; storage.nodes = new NodeType[max]; // pointer to the dynamically allocated array of nodes InitializeMemory(maxItems, storage); listData = NUL; // index of an array}
ListType::ListType(){ length = 0; maxItems = 500; storage.nodes = new NodeType[500]; InitializeMemory(500, storage); listData = NUL;}
ListType::~ListType(){ delete [] storage.nodes;}
void InsertItem(ItemType item){ // STUB: REPLACE WITH USEFUL CODE.}
50expanded by J. Goetz
Composition (containment)• Composition (or containment) means that an
internal data member of one class is defined to be an object of another class type.
A FAMILIAR EXAMPLE . . .
51expanded by J. Goetz
Private data
value
ComparedTo
Initialize
class ItemType
ItemType Class Interface Diagram
52expanded by J. Goetz
Sorted list contains an array of ItemType
SortedType class
IsFull
LengthIs
ResetList
DeleteItem
InsertItem
MakeEmpty
RetrieveItem
Private data:
length
info [ 0 ] [ 1 ] [ 2 ]
[MAX_ITEMS-1]
currentPos
GetNextItem
53expanded by J. Goetz
Inheritance• Inheritance is a means by which one class
acquires the properties--both data and operations--of another class.
• When this occurs, the class being inherited from is called the Base Class.
• The class that inherits is called the Derived Class.
AN EXAMPLE . . .
54expanded by J. Goetz
Inheritance
A derived class generally is longer but represents a smaller set of more specific objects than its base class (superclass)
• An object of derived class can be treated as an object of its corresponding base class, but the reverse is not true, so
• Derived object “is a” base class object through inheritance
• Reusability can be achieved via inheritance
55expanded by J. Goetz
Recall Definition of Queue• Logical (or ADT) level: A queue is an
ordered group of homogeneous items (elements), in which new elements are added at one end (the rear), and elements are removed from the other end (the front).
• A queue is a FIFO “first in, first out” structure.
expanded by J. Goetz
Queue ADT Operations• MakeEmpty -- Sets queue to an empty state.
• IsEmpty -- Determines whether the queue is currently empty.
• IsFull -- Determines whether the queue is currently full.
• Enqueue (ItemType newItem) -- Adds newItem to the rear of the queue.
• Dequeue (ItemType& item) -- Removes the item at the front
of the queue and returns it in item.
56
57expanded by J. Goetz
Class interface diagram for class QueType<char>
QueType
~QueType
Enqueue
Dequeue . . .
Private Data:
Front
Rear
‘C’ ‘Z’ ‘T’
58expanded by J. Goetz
// DYNAMICALLY LINKED IMPLEMENTATION OF QUEUE
#include "ItemType.h" // for ItemType
template<class ItemType>class QueType {public:
QueType( ); // CONSTRUCTOR~QueType( ) ; // DESTRUCTORbool IsEmpty( ) const;bool IsFull( ) const;void Enqueue( ItemType item );void Dequeue( ItemType& item );void MakeEmpty( );
private:NodeType<ItemType>* Front;NodeType<ItemType>* Rear;
};58
59expanded by J. Goetz 59
// DERIVED CLASS CountedQue FROM BASE CLASS QueType
template<class ItemType>class CountedQue : public QueType<ItemType> // “:” CountedQue is derived
// from QueType
{public:
CountedQue( ); void Enqueue( ItemType newItem );//redefining the inherited functionvoid Dequeue( ItemType& item ); //redefining the inherited functionint LengthIs( ) const; // new// Returns number of items on the counted queue.
private:int length; // new
};
SAYS ALL PUBLIC MEMBERS OF QueType CAN BEINVOKED FOR OBJECTS OF TYPE CountedQue
60expanded by J. Goetz
Class interface diagram for class
CountedQue<char>
QueType
~QueType
Enqueue
Dequeue . . .
Private Data:
Front
Rear
‘C’ ‘Z’ ‘T’
CountedQue
LengthIs
Enqueue
Dequeue . . .
Private Data:
length 3
61expanded by J. Goetz 61
// Member function definitions for class CountedQue
// Constructor initializertemplate<class ItemType> CountedQue<ItemType>::CountedQue( ) : QueType<ItemType>( )//”:” – it causes the invocation of the base-class constructor{
length = 0 ;}
template<class ItemType>int CountedQue<ItemType>::LengthIs( ) const{
return length ;}
62expanded by J. Goetz
template<class ItemType>void CountedQue<ItemType>::Enqueue( ItemType newItem )
// Adds newItem to the rear of the queue.// Increments length.
{length++;
QueType<ItemType>::Enqueue( newItem );}
template<class ItemType>void CountedQue<ItemType>::Dequeue(ItemType& item )
// Removes item from the rear of the queue.// Decrements length.
{length--;
QueType<ItemType>::Dequeue( item );} 62
63expanded by J. Goetz
// File: VirDemo.cpp// This program demonstrates the use of Polymorhism with virtual functions.#include <iostream>// specificationclass One{public: virtual void Print(); // virtual function !!!}; // end of Oneclass Two : public One{public: void Print(); // virtual because Print is virtual in One – in all derived classes as well}; // end of One // Function definitions:void One::Print(){ using namespace std; cout << "Print member function of class One" << endl;}void Two::Print(){ using namespace std; cout << "Print member function of class Two" << endl;}
void PrintTest(One* ); // prototype
int main(){ using namespace std; One* onePtr; onePtr = new One; // points to the base class cout << "Result of passing an object of class One: " ; PrintTest(onePtr); onePtr = new Two; // points to the derived class using the base class pointer cout << "Result of passing an object of class Two: "; PrintTest(onePtr); return 0;}
void PrintTest(One* ptr) { ptr->Print();} // formal parameter must be a base class type, because// an object of derived class can be treated as an object of its corresponding base class, so it can be passed also.