+ All Categories
Home > Documents > Lecture 5 OOP Course. 5. Templates Motivation A function for finding minimum value For floats we...

Lecture 5 OOP Course. 5. Templates Motivation A function for finding minimum value For floats we...

Date post: 22-Dec-2015
Category:
View: 213 times
Download: 0 times
Share this document with a friend
Popular Tags:
33
Lecture 5 Lecture 5 OOP Course
Transcript

Lecture 5Lecture 5

OOP Course

5. Templates5. Templates

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

Example: Ordered listExample: Ordered list

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


Recommended