Post on 21-Jan-2016
Ch7 1
Chapter 7
Templates
Ch7 2
Motivation for Templates
You want a list of shapes list of frames
How can you write one list class? List all ways you can think of List pros/cons of each method
Ch7 3
One Way to Look at Templates...
Until now, we used variables. The type of vars is fixed when you write code. The value of vars isn’t fixed when you write code.
With templates, type isn’t fixed when you write code!
You can sort of use a type as a variable!
Ch7 4
Template Example:Queue of some type blah
template <class BlahBlah> class Queue {
private:BlahBlah buffer[100];int head, tail, count;
public:Queue();void Insert(BlahBlah item);BlahBlah Remove();~Queue();
};
Parameter, can be any type
KeywordsKeywordsEither a class or method definition
starts here.
Ch7 5
Templates
Definition of “template”:Parameterized class with parameters.Parameters denote unknown type.
Usage:Situations where same algorithms & data
structures are applied to different data types
Syntax Example:template <class BlahBlah> class Queue {...}
Ch7 6
What can a Parameter be used for?
1. as type of local data to class:private:
BlahBlah buffer[100];
2. as method argument type:void Insert(BlahBlah item);
3. as method return type:BlahBlah Remove();
Ch7 7
Instantiating a template
Given:template <class BlahBlah> class Queue {...}
Instantiate Queue of ints in 2 ways:
Queue<int> intQueue;
typedef Queue<int> IntegerQueue; IntegerQueue intQueue;
Both of these define an object intQueue.Both of these define an object intQueue.
Ch7 8
Usage of Templates
intQueue.Insert(100); // add 100intQueue.Insert(200); // add 200int x = intQueue.Remove(); // remove 100intQueue.Insert(300); // queue now // has (200,300)int x = intQueue.Size(); // size is 2
Ch7 9
Compiler view of templates...
Compiler macro expands template code: You write Queue<int> intQueue; Compiler emits new copy of a class named
“Queueint” & substitutes <int> for <blahblah>
Therefore, all template code goes in a header file
Soprivate:
BlahBlah buffer[100];becomes
private:Queueint buffer[100];
Ch7 10
Syntax for Implementing Template Class Methods
template<class BlahBlah> Queue<BlahBlah> ::Queue() { ... }
template<class BlahBlah> void Queue<BlahBlah>::Insert(BlahBlah item)
{ ... }template<class BlahBlah> BlahBlah Queue<BlahBlah>::Remove() { ... }template<class BlahBlah> int
Queue<BlahBlah>::Size() { ... }template<class BlahBlah> Queue<BlahBlah>::~Queue() { ... }
return type
Ch7 11
A Complete Template Class
template <class BlahBlah> class Queue { private: BlahBlah buffer[100]; int head, tail, count; public:
Queue(); void Insert(BlahBlah item); BlahBlah Remove(); int Size(); ~Queue();};
Using the templateparameter: arg type,
ret type, data.
All template codegoes in a header file
Ch7 12
A Complete Template Class (Continued)
template <class BlahBlah> Queue<BlahBlah>::Queue():count(0), head(0), tail(0)
{}
template<class BlahBlah> voidQueue<BlahBlah>::Insert(BlahBlah item) {
assert(count <100);buffer[tail] = item;
tail = (tail + 1)% 100; count++;}
header file
Ch7 13
A Complete Template Class (Continued)
template <class BlahBlah> BlahBlah Queue<BlahBlah>::Remove() {
assert(count > 0);int val = head;head = (head + 1)%100;count--;return buffer[val];
}template <class BlahBlah> int
Queue<BlahBlah>::Size() {return count;}
template <class BlahBlah>Queue<BlahBlah> ::~Queue() {}
header file
Ch7 14
Recap
Note that method bodies… Use same algorithm for queue of ints,
Shapes, … But compiler still type checks!
(It does macro expansion, so if you declareQueue<int>
Queue<char>
compiler has two different classes after expansion to use with normal type checking rules.)
Ch7 15
3 Implicit Assumptions on Template Parameters: QueueExample
1. Declaration of the array of BlahBlahs:Assumes BlahBlah has no-args constructortemplate <class BlahBlah> class Queue {
private: BlahBlah buffer[100];
... };2. Assignment of BlahBlahs:
Assumes BlahBlah has appropriately assignment operator.template <class BlahBlah> void
Queue<BlahBlah> ::Insert(BlahBlah item){ ...
buffer[tail] = item;...
};
Ch7 16
3 Implicit Assumptions on Template Parameters: QueueExample (Contd.)
3. The way that BlahBlahs are returned by Remove method:Assumes BlahBlah has appropriate copy constructor.
template <class BlahBlah> BlahBlahQueue<BlahBlah>::Remove(){...return buffer[val];
}
Ch7 17
Morale:
Have fun decoding those compiler error messages!
Ch7 18
More complex template...
Template “Displayable” Points to a TextBox Knows how to set TextBox to a string Knows how to retrieve value from
TextBox Want template arg to be class
(OctalNumber, int, …)
Section 7.2
Ch7 19
The Displayable Template
template <class T> class Displayable { private:
T* displayed;TextBox* textBox;
public:Displayable(TextBox* tbox); void ShowThis(T* d); void Show(); void Reset(); ~Displayable();
};
Ch7 20
Implementation of the Displayable Template
template <class T> Displayable<T>::Displayable(TextBox *tbox) {textBox = tbox; displayed = (T*)0;}
template <class T> Displayable<T>::ShowThis(T* d) { displayed = d; }
template <class T> Displayable<T>::Show() { textBox->SetText(displayed ->ToString()); }
template <class T> Displayable<T>::Reset(T* d) { displayed->FromString() (textBox->GetText()); }
Assumption: T has ToString(), FromString methods
Ch7 21
Variable and Constant Template Parameters
Template parameters may be Classes
we saw this previously
VariablesE.g., to specify a size for a data structure
ConstantsUseful to define templates for special cases
Section 7.3
Ch7 22
Queue Template Class Queue Template Class with a Variable Parameterwith a Variable Parameter
template <class BlahBlah, int size> class Queue {
private: BlahBlah buffer[size]; int head, tail, count;
public: Queue(); void Insert(BlahBlah item); BlahBlah Remove(); int Size(); ~Queue();
};
Ch7 23
Usage of Template Class Usage of Template Class with a Variable Parameterwith a Variable Parameter
Queue<int,100> smallIntegerQueue; Queue<int, 1000> largeIntegerQueue; Queue<int, 1000> largeIntegerQueue2; Queue<float, 100> smallRealQueue; Queue<float, 1000> largeRealQueue;
smallIntegerQueue = largeIntegerQueue;
smallIntegetQueue = smallRealQueue;
largeIntegerQueue = largeIntegerQueue2;
Are theselegal?
Ch7 24
Constant ParameterConstant Parameter
class Displayable<int> { private: int* displayed; TextBox* textBox; char* ToString(int v); int FromString(char* text); public: Displayable(TextBox* tbox); // textbox to show in void ShowThis(int* d); // what to show void Show(); // show current value void Reset(); // reset value from // textBox ~Displayable(); };
int does not defineToString or FromString
Special cases are sometimes desired
Ch7 25
Special Case Displayable Template Special Case Displayable Template
(Continued)(Continued)
char* Displayable<int>::ToString(int v) { char* buf = new char[10]; ostrstream format(buf); format << v; return buf;}
int Displayable<int>::FromString(char* text) { istrstream(text) format; int value; format >> value; return value; }
Ch7 26
Partial Definition of the List Template: Partial Definition of the List Template: A Related Templates ExampleA Related Templates Example
template <class BaseType> class List { private: ... public: List(); void First(); void Next(); int Done(); BaseType& Current(); void Insert(BaseType val); void Delete(); ~List(); };
Section 7.4
Ch7 27
The Node TemplateThe Node Template
template <class BaseType> class Node { private: BaseType value; Node<BaseType> *next;
public: Node(BaseType base); BaseType& Value(); void ConnectTo(Node<BaseType>* nxt); Node<BaseType>* Next(); ~Node();};
Ch7 28
Implementation of the Node TemplateImplementation of the Node Template
template <class BaseType> Node<BaseType>::Node(BaseType base) :value(base), next(0) {}
template <class BaseType> BaseType& Node<BaseType>::Value(){return value;}
template <class BaseType> void Node<BaseType>::ConnectTo(Node<BaseType>* nxt) {next = nxt; }
template <class BaseType> Node<BaseType>* Node<BaseType>::Next() {return next; }
template <class BaseType> Node<BaseType>::~Node(){}
Ch7 29
Relationship Between the List and Node Relationship Between the List and Node TemplatesTemplates
template <class BaseType> class List {
private: Node<BaseType> *head; // beginning of list Node<BaseType> *current; // current element Node<BaseType> *previous; // previous element; // needed for deletion public:
... // shown above};
Ch7 30
Implementation of InsertImplementation of Insert
template <class BaseType> void List<BaseType>::Insert(BaseType val) { Node<BaseType> *newNode = new Node <BaseType> (val); if (!head) { head = current = newNode; return; } assert(current); newNode->ConnectTo(current->Next()); current->ConnectTo(newNode); current = newNode; }
Ch7 31
Implementation of DeleteImplementation of Delete
template <class BaseType> void List<BaseType>::Delete() { assert(current); Node<BaseType> *temp = current; if(current == head) { head = head->Next(); current = head; delete temp; return; } assert(previous); current = current->Next(); previous->ConnectTo(current); delete temp;}
Ch7 32
Templates and Inheritance
Template may inherit from TemplateNon-template may inherit from
TemplateTemplate may inherit from non-
templateTemplates may use multiple
inheritence
Section 7.5
Ch7 33
Inheritance Between Inheritance Between TemplatesTemplates
template <class BlahBlah> class Queue {
private: BlahBlah buffer[100]; int head, tail, count;
public: Queue(); void Insert(BlahBlah item); BlahBlah Remove(); ~Queue();
};
Ch7 34
Inheritance Between Inheritance Between Templates (cont’d)Templates (cont’d)
template <class BlahBlah> class InspectableQueue : public Queue<BlahBlah>{ public: InspectableQueue(); BlahBlah Inspect(); // return without removing the //first element ~InspectableQueue();};
Base class is elaborated with same
parameterized type
Ch7 35
Using InspectableQueue Using InspectableQueue TemplateTemplate
InspectableQueue<Location> locations;Location loc1(...);Location loc2(...); ...locations.Insert(loc1); // base class methodlocations.Insert(loc2); // base class method ...Location front = locations.Remove(); // base class methodLocation newFront = locations.Inspect(); // derived class // method
Ch7 36
NonTemplate Inheriting NonTemplate Inheriting from Templatefrom Template
template <class BaseType> class List { private: ... public: List(); void First(); void Next(); int Done(); BaseType& Current(); void Insert(BaseType val); void Delete(); ~List();};
Ch7 37
Polygon Class Inherits from Polygon Class Inherits from List TemplateList Template
class Polygon : public List<Location> // Polygon "is-a" list of Locations{ public: Polygon(); void Draw(Canvas& canvas); // draw itself};
Base class is elaborated with a
specific type
Ch7 38
Using Polygon ClassUsing Polygon Class
Polygon poly; ...poly.Insert(Location(20,20)); // inherited from templatepoly.Insert(Location(30,30)); // inherited from template
// insert other locations
poly.Draw(canvas); // derived class method
Ch7 39
The Sequenced Interface and the Clock Class
class SequencedInterface{ public: virtual void Show() = 0; virtual void Next() = 0;};
Ch7 40
The Sequenced Interface and the Clock Class (Contd.)
class Clock{ private:
SequencedInerface *sequenced; public:
Clock() {}void ConnectTo(SequencedInterface& sq)
{ sequenced = &sq;}void ConnectTo(SequencedInterface* sq){ sequenced = sq;}void Notify() { sequenced->Next();
sequenced->Show(); }};
Ch7 41
Defining the ImplementsSequenced Template by Inheritance from a Non-Template Class
template class <SequencedImplementation> class Sequenced : public SequencedInterface { private:
SequencedImplementation& seqItem; public: Sequenced(SequencedImplementation& item) : seqItem(item) {}
void Next() { seqItem.Next();} void Show() { seqItem.Show();}};
Ch7 42
Usage of the ImplementsSequenced Template
Clock timer;
Counter time(0); ...Sequenced <Counter> timedCounter(time); ...timer.ConnectTo( (SequencedInterface&)timedCounter ); ..timer.Notify(); // invokes Next and Show in time object
Ch7 43
Templates Using Multiple Inheritance
template class <SequencedImplementation> class Sequenced : public SequencedInterface { private: SequencedImplementation& seqItem; public: Sequenced(SequencedImplementation& item) :
seqItem(item) {} void Next() { seqItem.Next();} void Show() { seqItem.Show();}
};
Ch7 44
Templates Using Multiple Inheritance (Contd.)
template class <SequencedImplementation> class SequencedObject
: public SequencedImplementation,public SequencedInterface
{ public:
SequencedObject(SequencedImplementation& item) :SequencedImplementation(item) {}void Next() { SequencedImplementation::Next();}void Show() { SequencedImplementation::Show();}
};
Ch7 45
Using the Sequenced and SequencedObject Templates
Clock timer;Counter time(0); ...Sequenced <Counter> timedCounter(time); ...timer.ConnectTo((SequencedInterface&)timedCounter ); ...timer.Notify();
Clock timer;Counter time(0);...SequencedObject <Counter> timedCounter(time);...timer.ConnectTo((SequencedInterface&)timedCounter );...timer.Notify();