Date post: | 22-Dec-2015 |
Category: |
Documents |
View: | 213 times |
Download: | 0 times |
MotivationMotivation• A function for finding minimum value
• For floats we will need another function
• Can we parameterize this function with a typetype?– Towards GenericGeneric Programming
– Like objects are generalized into classes, we would like to generalize classes and functions into templatestemplates
int min(int a, int b){return (a<b ?
a : b)}
float min(float a, float b){return (a<b ? a
: b)}
void swap(int& a, int& b){ int temp = a; a = b; b = temp;}
void swap(char& a, char& b){ char temp = a; a = b; b = temp;}
void swap(float& a, float& b){ float temp = a; a = b; b = temp;}
void swap(short& a, short& b){ short temp = a; a = b; b = temp;}
void swap(boolean& a, boolean& b){ boolean temp = a; a = b; b = temp;}
void swap(double& a, double& b){ double temp = a; a = b; b = temp;}
void swap(string& a, string& b){ string temp = a; a = b; b = temp;} void swap(Parrot& a, Parrot& b){
Parrot temp = a; a = b; b = temp;}
void swap(Cat& a, Cat& b){ Cat temp = a; a = b; b = temp;}
void swap(Elephant& a, Elephant& b){ Elephant temp = a; a = b; b = temp;}
void swap(Snake& a, Snake& b){ Snake temp = a; a = b; b = temp;} void swap(Crocodile& a, Crocodile& b){
Crocodile temp = a; a = b; b = temp;}
void swap(Eagle& a, Eagle& b){ Eagle temp = a; a = b; b = temp;}
MotivationMotivation
TemplatesTemplates
• C++ provides a super macro mechanismsuper macro mechanism that is identified by the keyword templatetemplate
• TemplatesTemplates can be thought of as MACROMACROs for functionsfunctions and classesclasses, that need not be explicitly called by the programmer
• TemplatesTemplates are controlled by the compilercompiler (and not by the pre-processorpre-processor)
• Templates argumentsTemplates arguments are either class-types or const-expressions of a fixed type
• Arguments that are passed to temple functions are checked for type-mismatch
Function TemplateFunction Template• Preserving the semantics of a function
• Automatically generatedAutomatically generated instance of a function, varying by type
• The programmer parameterizes all or a subset of the types in the interface
• The function implementation remains invariantinvariant over a set of function instancesfunction instances, each handling a unique data typeunique data type
template <class Type>
Type min(Type a, Type b) {
return ( a>b ? a : b);
}
Function Temples Cont.Function Temples Cont.
TemplateTemplate <calsscalss TT>TT min(TT a, TT b){
return (a<b ? a : b)} operator< should be
defined for calss T
Declaration
int main(){ intint a=3, b=4; charchar c= ‘a’, d = ‘b’;cout << min(a,b); // o.kcout << min(c,d); // o.kcout << min(a,c); // Error!!return 0;
Usage
Defining additional functionint min(int, int)
Will prevent the compilation error
Function Temples Cont.Function Temples Cont.• For each calleach call to a function template, the compiler
will try to generate an actual functiongenerate an actual function with the appropriate prototype
• OverloadingOverloading for function of the same name is done in this order:
– Look for an exactexact match among non-template functions– Look for an exactexact match that can be generated from
function template– Look for the best match non-template functions, using
1. Trivial conversion
2. Promotions (e.g. short to int)
3. Standard conversions (e.g. int to double)
4. User-defined conversions (e.g. double to complex)
Class TemplatesClass Templates
• Class templatesClass templates are used to define generic classes
• An actual classactual class is created only when an actual object defined, using the class template with actual parameters
templetetemplete<classclass E, intint size> classclass Buffer;
BufferBuffer<char*char*, 1024> buf_chrp;BufferBuffer<intint, 1024> buf_int;
Example: class BagExample: class Bag
• addadd• getOnegetOne• isEmptyisEmpty• isFullisFull• currentSizecurrentSize• capacitycapacity
Bags With and Without TemplatesBags With and Without Templates
// BagOfInt.h
#define CAPACITY 50
class BagOfInt{
public:
BagOfInt(unsigned int
max_capacity=CAPACITY);
~BagOfInt( );
// cont’d..
// Bag.h (template class)
#define CAPACITY 50
template <class Item>template <class Item>
class Bag {
public:
Bag(unsigned int
max_capacity=CAPACITY);
~Bag( );
// cont’d..
Bags With and Without TemplatesBags With and Without Templates
// …BagOfInt.h cont’d
bool add( intint * value );
intint * getOne( );
bool isEmpty( ) const;
bool isFull( ) const;
unsigned int currentSize( )
const;
unsigned int capacity( )
const;
// cont’d..
// …Bag.h cont’d (template)
bool add( ItemItem * value );
ItemItem * getOne( );
bool isEmpty( ) const;
bool isFull( ) const;
unsigned int currentSize( )
const;
unsigned int capacity( )
const;
// cont’d..
Bags With and Without TemplatesBags With and Without Templates
// …BagOfInt.h cont’d
private:
unsigned int m_size;
unsigned int m_max_capacity;
intint ** m_container;
};
// end of BagOfInt.h
// …Bag.h cont’d(template)
private:
unsigned int m_size;
unsigned int m_max_capacity;
ItemItem ** m_container;
};
#include "Bag.template"
// end of Bag.h
Bags With and Without TemplatesBags With and Without Templates
• Differences between .template, .cpp files:– Occurrences of BagOfInt ::BagOfInt :: are replaced by
Bag<Item> ::Bag<Item> ::– Member functions, constructors, destructor
are preceded by templatetemplate <class Item><class Item>– Constructors are BagBag; destructor is ~Bag~Bag
• Assumption: Item is a class – See use of NULL in add, getOne
Bags With and Without TemplatesBags With and Without Templates
// BagOfInt.cpp
#include “BagOfInt.h”
#include <stdlib.h>
#include <time.h>
// continued on next slide
// Bag.template
#include “Bag.h”
#include <stdlib.h>
#include <time.h>
// continued on next slide
Bags With and Without TemplatesBags With and Without Templates
BagOfInt :: BagOfInt(unsigned int max_capacity)
{
m_max_capacity = max_capacity; m_size = 0;
m_container = new intint*[m_max_capacity];
srand( (unsigned int) time( NULL ) );
} // cont’d ..
template <class Item>template <class Item>
Bag<Item> :: Bag (unsigned int max_capacity)
{
m_max_capacity = max_capacity; m_size = 0;
m_container = new ItemItem*[m_max_capacity];
srand( (unsigned int) time( NULL ) );
} // cont’d ..
Bags With and Without TemplatesBags With and Without Templates
BagOfInt :: ~BagOfInt( ) {
delete [ ] m_container;
} // cont’d..
template <class Item>template <class Item>
Bag<Item> :: ~Bag( ) {
delete [ ] m_container;
} // cont’d..
Bags With and Without TemplatesBags With and Without Templates
bool BagOfInt :: add(intint* value) {
if (isFull() || (value == NULL) ) return false;
m_container[m_size] = value; m_size++;
return true;
} // cont’d..
template <class Itemtemplate <class Item>
bool Bag<Item> :: add(ItemItem * value) {
if (isFull( ) || (value == NULL) ) return false;
m_container[m_size] = value; m_size++;
return true;
} // cont’d..
Bags With and Without TemplatesBags With and Without Templates
intint * BagOfInt :: getOne( ) {
if (isEmpty( )) return NULL;
unsigned int index = (unsigned int)( rand() * m_size
/ (RAND_MAX+1));
int* value = m_container[index];
m_container[index] = m_container[m_size-1];
m_size--; return value; } // cont’d..template <class Item>template <class Item>
ItemItem * Bag<Item> :: getOne( ) {
if (isEmpty( )) return NULL;
unsigned int index = (unsigned int)( rand( ) * m_size
/ (RAND_MAX+1));
ItemItem* value = m_container[index];
m_container[index] = m_container[m_size-1];
m_size--; return value; } // cont’d..
Bags With and Without TemplatesBags With and Without Templates
bool BagOfInt :: isEmpty( ) const { return (m_size == 0); }
bool BagOfInt :: isFull( ) const {return (m_size == m_max_capacity ); }
// cont’d..
template <class Item>template <class Item>
bool Bag<Item> :: isEmpty( ) const { return (m_size == 0); }
template <class Item>template <class Item>
bool Bag<Item> :: isFull( ) const {return (m_size == m_max_capacity); }
// cont’d..
Bags With and Without TemplatesBags With and Without Templates
unsigned int BagOfInt :: currentSize( ) const { return m_size; }
unsigned int BagOfInt :: capacity( ) const {return m_max_capacity; }
// end of Bag_Ptr.cpp
template <class Item>template <class Item>
unsigned int Bag<Item> :: currentSize( ) const { return m_size; }
template <class Item>template <class Item>
unsigned int Bag<Item> :: capacity( ) const {return m_max_capacity;}
// end of Bag.template
Instantiating Bag ObjectsInstantiating Bag Objects
Bag<int> bag(40);
// locally allocated bagbag for 40 ptrs to intint
Bag<int> *bagPtr = new Bag<int>(60);
// bagPtr holds the address of a dynamically // allocated bagbag that stores up to 60 pointers to intint
Bag< Bag<int> > x(25);
// locally allocated. bag x can hold 25 pointers to // bagsbags, each of which can hold pointers to intint
Bag< Bag<int > > *y = new Bag< Bag<int > > (30);
// y holds the address of a dynamically allocated bagbag // that stores up to 30 pointers to bagsbags of pointers
// to int
Instantiating Bag ObjectsInstantiating Bag Objects
• When Bag<Bag<int>> *y = new Bag<Bag<int>>(30); is first encountered:– First, the class Bag<int> is instantiated– Then the class Bag<Bag<int>> is instantiated– Then the object y is instantiated
• When Bag<int> and Bag<Bag<int>> are encountered subsequently, the classes already exist
Operations on OrderedListOperations on OrderedList
OrderedList
Construct an empty ordered list of objects
isEmpty Determine whether or not the list is empty
getLength Get the current size of the list
remove Remove value at a given position from the list
retrieve Get the Item at a particular location in the list
insert Add an object to the list in a sorted ordersorted order
find Return the position of a particular object in the list
Assuming we already have the class List<Item>List<Item>, orderedList<Item>orderedList<Item> will use List<Item> to store the elements in a sorted order
OrderedList.hOrderedList.h#include “List.h”
template <class Item>
class OrderedList {
public:
OrderedList(unsigned int capacity = MAX_LIST); // constructor for an empty ordered list that // can hold up to capacity items; default // size is defined in List.h
~OrderedList( ); // destructor
bool isEmpty( ) const;
// true if list is empty, false otherwise
OrderedList.hOrderedList.h
int getLength( ) const;
// returns the current size of the list
Item remove (unsigned int pos);
// remove the value at location pos and return it
// precondition: pos must be a legal list position
Item retrieve (unsigned int pos) const;
// return value at pos without modifying the list. // precondition: pos must be a legal list position
// cont’d..
OrderedList.hOrderedList.h
void insert (Item item);
// insert item at appropriate pos’n in list
int find (Item item) const;
// return pos’n of first occurrence of
// item, or -1 if item isn’t found
private:
List<Item> m_container;
// to hold the list of Items
};
// end of header file
OrderedList.templateOrderedList.template
#include <stdlib.h>
template <class Item>
OrderedList<Item> :: OrderedList (unsigned int capacity ) : m_container(capacity)
{ }
template <class Item>
OrderedList<Item> :: ~OrderedList ( )
{ } // cont’d..
OrderedList.templateOrderedList.template
template <class Item>
bool OrderedList<Item> :: isEmpty( ) const {
return m_container.isEmpty( );
}
template <class Item>
int OrderedList<Item> :: getLength( ) const {
return m_container.getLength( );
}
// cont’d..
OrderedList.templateOrderedList.template
template <class Item>
Item OrderedList<Item> :: remove (unsigned int pos) {
return m_container.remove(pos);
}
template <class Item>
Item OrderedList<Item> :: retrieve (unsigned int pos) const {
return m_container.retrieve(pos);
} // cont’d..
OrderedList.templateOrderedList.template
template <class Item>
void OrderedList<Item> :: insert (Item item) {
for ( int k = 1; k <= getLength( ); k++ )
if ( item < retrieve(k) )
break;
m_container.insert( k, item );
} // cont’d..
OrderedList.templateOrderedList.template
template <class Item>
int OrderedList<Item> :: find (Item item) const {
for ( int k=1; k <= getLength( ); k++ )
if ( item == retrieve(k) )
return k;
return –1;
} // end of OrderedList implementation
Next lecture: we will see a better way to implement OrederedList<Item>OrederedList<Item>, using
InheritanceInheritance