610 likes | 773 Views
CE00314-2 Further Programming Concepts in C++. Lecture 6 Collections & Templates. Introduction. Part 1 Collections Static - Dynamic Template definition Function templates Class templates Part 2 Adaptable collections Further inheritance. Collections. Arrays Dynamic collections
E N D
CE00314-2Further Programming Concepts in C++ Lecture 6 Collections & Templates
Introduction • Part 1 Collections • Static - Dynamic • Template definition • Function templates • Class templates • Part 2 Adaptable collections • Further inheritance
Collections • Arrays • Dynamic collections • Linked lists • Constructed within application (specific) • Generic linked list class • Template implementation of generic l. list • Standard Template Library contains • Vectors • Linked Lists • Other STLs
Array of accounts COLLECTIONS • Array initialisation int b[5] = {75,25,100,-45,60}; Account acct[3] = {Account(500,5,0.6), Account(), Account(100.0) };
An array of various accounts • main() { Savings acc1(100.0); Time acc2(500.0, 100.0); Investment acc3(101.5, 6.5); Account* staffacct[3] = { &acc1, &acc2, &acc3} for(i = 0; i<3; i++) { staffacct[i]->print(); }
Arrays and new • Arrays can be created with new • int* p = new int[10]; • elements are accessed using subscripts p[0],p[1] ... • similarly for objects: Account * acs = new Account[20]; cout<< acs[0]->balance();
Deleting Objects • Once an object created with new is finished it can be destroyed using delete • delete ac1; • If the pointer points to an array it is necessary to tell C++ this by writing: • delete [ ] p;
Dynamic Collections • Arrays are a fixed size although can be resized dynamically by using memory management features used in C • Dynamic structres ccccna be used to allow collection to shrink and grow dynamically • Different implementations exist
Comparing Implementations • Fixed size versus dynamic size • A statically allocated array • Prevents the enqueue operation from adding an item to the queue if the array is full • A resizable array or a reference-based implementation • Does not impose this restriction on the enqueue operation
Comparing Implementations • Pointer-based implementations • A linked list implementation • More efficient • The ADT list implementation • Simpler to write
A Summary of Position-Oriented ADTs • Position-oriented ADTs • List • Stack • Queue • Stacks and queues • Only the end positions can be accessed • Lists • All positions can be accessed
A Summary of Position-Oriented ADTs • Stacks and queues are very similar • Operations of stacks and queues can be paired off as • createStack and createQueue • Stack isEmpty and queue isEmpty • push and enqueue • pop and dequeue • Stack getTop and queue getFront
A Summary of Position-Oriented ADTs • ADT list operations generalize stack and queue operations • getLength • insert • remove • retrieve
ADT objects • Rely on use of an Abstract Class which contains the referencing mechanism and allows objects to be included in the collections.
ABSTRACT BASE CLASSES • class Object { public: Object(){;} virtual ~Object(){;} virtual ostream& printOn(ostream&) const = 0; friend ostream& operator<<(ostream& out, const Object& ob) { ob.printOn(out); return out; } }
A linked List class Entry{ public: Entry *next; Object *info; Entry( Object *obj ) {info = obj; next = 0; } ~Entry() { if( ! (info==0) ) delete info; } };
Use this as data for linked list class List { private: Entry *head; int NoEntries; public: List() { head = 0; NoEntries=0;} ~List();
linked list cont. Entry* returnHead() const { return head ;} void add( Object& ); int isEmpty(){return head == 0;} };
Linked list void List::add( Object& newEntry ) { Entry *newElement = new Entry( &newEntry ); newElement->next = head; head = newElement; NoEntries++; }
Destructor • List::~List() { while(head != 0) { Entry* temp = head; head = head-> next; delete temp; } }
Container Class • As can be seen form the previous example the object is a Node which is part of a list • The list is an example of a container class
Container Classes • Container classes are an important category of ADTs • They are used to maintain collections of elements like stacks, queues, linked lists, tables,trees, etc. • Container classes form the basis for various C++ class libraries • C++ container classes can be implemented using several methods: • Ad hoc, rewrite from scratch each time • A generic class facility (eg. list class with list nodes) • Parameterised Types (use of templates to generalise the class) • void Pointer Method (allows heterogenous collections)
Example Pointer Method • Generic ADT List container class • 4 basic operations • Insert • Membership (e.g. IsInList) • Removal • Iteration (e.g. Display routine)
protected: class Node f friend List; public: Node (void *, Node *n = 0); ~Node (void); void add to front (void *); void add to end (void *); Node *remove (void *); private: void *element ; // Pointer to actual data Node *next ; }; Example Applications Generic List.h #ifndef Generic List #define Generic List class List { public: List (void); ~List (void); void remove current (void); // Used as iterators: : : void reset (void); void next (void);
Generic List.h (cont'd) protected: // used by subclasses for implementation void add to end (void *); void add to front (void *); Node *current value (void); void *current (void); bool includes (void *); void *remove (void *); // important to make match virtual! virtual bool match (void *, void *); private: Node *head ; Node *iter ; //used to iterate over lists }; // Iterator functions inline List::Node *List::current value (void) { return this->iter ; } inline void List::reset (void) { this->iter = this->head ; } inline void *List::current (void) { if (this->iter ) return this->iter ->element ; else return 0; } inline void List::next (void) { this->iter = this->iter->next ; }
Class templates • Class templates enable reusable data types to be easily created • Often called generic programming • For example we can create a generic stack (a last in first out data structure) using class templates • The generic stack can be instantiated with any data type • Stack of integers, stack of doubles, stack of dates etc
// Stack class template template <class T> class Stack { private: int size; // No. of elements in the stack int top; // Location of the top element T* stackPtr; // Pointer to the stack public: Stack(int); ~Stack() { delete[] stackPtr; } int push(const T&); // Push an element int pop(T&); // Pop an element int isEmpty() { return top==-1;} int isFull() { return top==size-1;} };
void main() { Stack<char> charStack(7); char[] name=“Michael”; int j=0; while(charStack.push(name[j]) j++; char c; cout << “My name in reverse is : “; while(charStack.pop(c)) cout << c; }
This code assumes that overloaded assignment operator function exist for programmer defined data types • This must be provided if the object used with the Stackclass contains dynamically allocated memory
Template Definition • Cambridge Dictionary • template1 a pattern made of metal, plastic or paper, which is used for making many copies of a shape or to help cut material accurately2 a system that helps you arrange information on a computer screen • C++ • Pattern for handling generic data
Function overloading • Swap revisited • To handle integersvoid swap(int& rnA, int& rnB){ int nTemp; nTemp = rnA; rnA = rnB; rnB = nTemp}
Function overloading • Swap revisited • To handle charactersvoid swap(char& rnA, char& rnB){ char nTemp; nTemp = rnA; rnA = rnB; rnB = nTemp}
Function overloading • Swap revisited • float, double ……. • Separate functions for each ?? • Generic function • Generic functionality • Generic data – automatically typed when used • Template function
Template function • Conceptuallyvoid swap(Type_of_Var& Var1, Type_of_Var& Var2){ Type_of_Var Temp; Temp = Var1; Var1 = Var2; Var2 = Temp;}
Template Function - syntax template<class T> // template prefix void swapValues(T& Var1, T& Var2) { T Temp; Temp = Var1; Var1 = Var2; Var2 = Temp; } • For demonstration see – Template1.cpp
Template functions - array print • Handling unspecified arrays • Array length?template<class T>void printArray(const T *array, constint nSize){for(int nCount = 0; nCount < nSize; nCount++) cout << array[nCount] << “ “; cout << endl;} • For usage example see – Template2.cpp
Template Functions - returning Also possible to have generic returntemplate<class T> T addValues(T Val1, T Val2) { return Val1 + Val2; } • See Template3.cpp for usage example
Template Functions – multiple types • Possible to have more than one type • template<class T1, class T2> • Must use all parameters • All must be utilised within function • See Template4.cpp • Possible to use Tx for casting and return type • See Template5.cpp
Template functions - Plenary • Produce generic solution • Data types provided at run time • Operators must be able to handle types • Overloaded operators included • Use of keyword “class” can be replaced with “typename” • ANSI/ISO standard allows • Programmers tend to use “class”
Class Templates • Syntax basically the same as when using function templates • must use keyword “class”template<class T>class Pair{private: T first; T second;private: Pair(); Pair(T Val1, T Val2); • etc….. • See Template6.cpp for further details
Class templates • So far….. • Class within main file • Could place within .h file • and include • See Template7.cpp • Shows use of Array of pointers • ? – mixed types?
Creating function templates from class templates • We can easily create a function template by passing a class template as an argument to a function • A classic example is a sort() function template which sorts the contents of a container template (for example and array) passed as an argument
We can then create a sort() function template template<class T> void sort(Vector<T>& v) { // sort the elements of v into increasing // order using a bubble sort int size=v.getSize(); for (int i=0; i<size-1; i++) for (int j=size; i<j; j--) if (v[j]<v[j-1]) // swap v[j] & v[i] { T t = v[j]; v[j]=v[j-1]; v[j-1] = t; } }
void main() { Vector<int>& vi(100); Vector<char*>& vc(100); Vector<float>& vf(100); Vector<Circle>& vci(100); // initialize the vectors // ….. . sort(vi); sort(vc); sort(vf); sort(vci); }
The compiler will try and create the correct sort() functions by instantiating the templated functions • It will run into 2 problems in this example • Instantiating sort() with a char* (a string) argument will produce incorrect results • The ‘<‘ operator will not test for alphabetical ordering of the strings • Instantiating sort() with a Circle object argument will produce a compilation error • We need an overloaded operator<() function defined on Circle objects
We can also create an operator<() function for Circle objects int operator < (Circle& c1,Circel& c2) { return c1.radius<c2.radius; }
Other features of templates • Templates and friends • With templates, friendship can be established between either a class template or a particular instantiation of the template and global/member functions or entire classes • A few examples will clarify this:
Declare a function f() to be a friend of every class specialization of class template X • Declare every member function of class Y to be a friend of every class specialization of class template X template<class T> class X { …. friend void f(); …. } template<class T> class X { …. friend class Y; …. }
The Standard Template Library (STL) • The Standard Template Library (STL) is an addition to the C++ Standard Library • Developed at the Hewlett-Packard Labs in the mid-late 90’s • STL defines powerful, template-based, reuseable components that implement many common data structures and algorithms to process those data structures • STL is extremely complex, being optimised for efficiency.
STL is based on 3 components • Containers • Iterators • Algorithms • Template-based containers are data structures used to group objects of any type • Examples include linked lists, vectors and sets • Iterators encapsulate the mechanisms used to access container elements • A simple pointer can be used as an iterator for a standard array